ipset-access: Null-Latenz-IP-Blockierung mit Linux-Kernel-ipsets (v2)
Erfordert den Pro-Plan (oder höher) des GetPageSpeed NGINX Extras Abonnements.
Installation
Sie können dieses Modul in jeder RHEL-basierten Distribution installieren, einschließlich, aber nicht beschränkt auf:
- RedHat Enterprise Linux 7, 8, 9 und 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 und Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-ipset-access
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-ipset-access
Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:
load_module modules/ngx_http_ipset_access.so;
Dieses Dokument beschreibt nginx-module-ipset-access v2.0.9, veröffentlicht am 20. Dezember 2025.
Unternehmensgerechte IP-basierte Zugriffskontrolle für NGINX unter Verwendung von Linux ipset. Blockieren Sie Bedrohungen, begrenzen Sie Missbrauch, fordern Sie Bots heraus und schützen Sie Ihre Infrastruktur.
⚠️ Kommerzielle Software
Dies ist ein Closed-Source-Premium-Modul, das ausschließlich über das GetPageSpeed Repository erhältlich ist.
✨ Funktionen
Kernfunktionen
| Funktion | Beschreibung |
|---|---|
| Whitelist/Blacklist | Erlauben oder verweigern basierend auf der ipset-Mitgliedschaft |
| Mehrere ipsets | Überprüfen gegen mehrere ipsets in einer Direktive |
| Live-Updates | Ändern Sie ipsets, ohne NGINX neu zu laden |
| Benutzerdefinierte Statuscodes | Geben Sie jeden HTTP-Status zurück, wenn blockiert |
Leistungsmerkmale
| Funktion | Beschreibung |
|---|---|
| Pro-Thread-Sitzungen | Thread-lokale libipset-Sitzungen beseitigen Lock-Kontention |
| LRU-Cache | Gemeinsamer Speichercache mit konfigurierbarem TTL |
| Cache-Trefferquoten | Typischerweise über 95 % Trefferquote reduziert Kernelaufrufe |
Sicherheitsmerkmale
| Funktion | Beschreibung |
|---|---|
| Ratenbegrenzung | Begrenzen Sie Anfragen pro IP mit konfigurierbaren Fenstern |
| Auto-Ban | Automatisches Blacklisting von Verstößern gegen die Ratenbegrenzung |
| JS-Herausforderung | Proof-of-Work-Herausforderung stoppt automatisierte Bots |
| Honeypot-Fallen | Automatisches Blacklisting von IPs, die Fallen-URLs treffen |
| Eingabe-Timeout | Automatisches Ablaufen von Blacklist-Einträgen |
Betriebsmerkmale
| Funktion | Beschreibung |
|---|---|
| Trockenlaufmodus | Testen Sie die Konfiguration, ohne zu blockieren |
| Fail-Open/Close | Steuern Sie das Verhalten bei ipset-Fehlern |
| Prometheus-Metriken | Natives /metrics-Endpunkt für Grafana |
| JSON-Statistiken | Detaillierte Statistik-API |
| NGINX-Variablen | $ipset_result und $ipset_matched_set |
🚀 Schnellstart
1. Erstellen Sie ipsets
## Erstellen Sie eine Blacklist
sudo ipset create bad_guys hash:ip timeout 86400
## Erstellen Sie eine Ratenbegrenzungs-Ban-Liste
sudo ipset create ratelimited hash:ip timeout 1800
## Erstellen Sie eine Honeypot-Fallenliste
sudo ipset create honeypot hash:ip timeout 86400
2. Konfigurieren Sie NGINX
load_module modules/ngx_http_ipset_access_module.so;
http {
server {
listen 80;
# Blockieren Sie bekannte schlechte IPs
ipset_blacklist bad_guys;
# Ratenbegrenzung: 100 Anfragen pro Minute
ipset_ratelimit rate=100 window=60s autoban=ratelimited;
# Ihr Inhalt
location / {
root /var/www/html;
}
# Honeypot-Falle - gibt standardmäßig 404 zurück
location /wp-admin.php {
ipset_autoadd honeypot timeout=86400;
}
# Metriken-Endpunkt
location /metrics {
ipset_metrics;
allow 127.0.0.1;
deny all;
}
}
}
3. Testen und neu laden
sudo nginx -t && sudo nginx -s reload
📦 Installation
Dieses Modul ist ausschließlich über das GetPageSpeed Premium Repository erhältlich.
Schritt 1: Abonnieren Sie das GetPageSpeed Repository
Besuchen Sie GetPageSpeed Repository Subscription, um Zugang zu erhalten.
Schritt 2: Installieren Sie das Repository
## RHEL/CentOS/Rocky/Alma Linux 8+
sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
Schritt 3: Installieren Sie das Modul
sudo dnf install nginx-module-ipset-access
Schritt 4: Aktivieren Sie das Modul
Fügen Sie zu /etc/nginx/nginx.conf vor allen http {}-Blöcken hinzu:
load_module modules/ngx_http_ipset_access_module.so;
Schritt 5: NGINX neu laden
sudo nginx -t && sudo systemctl reload nginx
📖 Konfigurationsreferenz
Zugriffskontrolle
ipset_blacklist set1 [set2 ...]
Kontext: http, server
Standard: —
Blockiert Anfragen, wenn die Client-IP in irgendeinem der aufgeführten ipsets erscheint. Mehrere ipsets werden der Reihe nach überprüft, bis ein Treffer gefunden wird.
## Einzelnes Set
ipset_blacklist bad_guys;
## Mehrere Sets (ODER-Logik - blockiert, wenn in IRGENDEINEM Set)
ipset_blacklist spammers hackers tor_exits;
## Deaktivieren
ipset_blacklist off;
ipset_whitelist set1 [set2 ...]
Kontext: http, server
Standard: —
Erlaubt Anfragen nur, wenn die Client-IP in mindestens einem der aufgeführten ipsets erscheint. Alle anderen IPs werden abgelehnt.
## Nur vertrauenswürdige IPs erlauben
ipset_whitelist trusted_partners office_ips;
Wichtig: Whitelisted IPs umgehen alle Modulbeschränkungen, einschließlich:
- Ratenbegrenzung (ipset_ratelimit)
- JavaScript-Herausforderungen (ipset_challenge)
Dies ist nützlich für Admin-IP-Adressen, die nicht den Ratenbegrenzungen oder Herausforderungen unterliegen sollten:
## Admin-IP-Adressen umgehen Ratenbegrenzung und Herausforderungen
ipset_whitelist admin_ips;
ipset_ratelimit rate=100 window=1m autoban=ratelimited ban_time=1800;
ipset_challenge on;
ipset_status code
Kontext: http, server
Standard: 403
HTTP-Statuscode, der zurückgegeben wird, wenn eine Anfrage blockiert wird.
ipset_status 403; # Verboten (Standard)
ipset_status 444; # Verbindung ohne Antwort schließen (NGINX-Spezial)
ipset_status 429; # Zu viele Anfragen
ipset_status 503; # Dienst nicht verfügbar
Caching & Leistung
ipset_cache_ttl time
Kontext: http, server
Standard: 60s
Wie lange die Ergebnisse von ipset-Lookups zwischengespeichert werden sollen. Zwischengespeicherte Ergebnisse vermeiden wiederholte Kernelaufrufe für dieselbe IP.
ipset_cache_ttl 30s; # 30 Sekunden
ipset_cache_ttl 5m; # 5 Minuten
ipset_cache_ttl 1h; # 1 Stunde
Debugging-Hinweis: Wenn Sie eine IP aus einem ipset entfernen, das Modul jedoch weiterhin als "übereinstimmend" meldet, liegt dies am Caching. Das zwischengespeicherte Ergebnis läuft nach der konfigurierten TTL ab. Für sofortige Wirkung während des Testens können Sie vorübergehend ipset_cache_ttl 0; setzen, um das Caching zu deaktivieren (nicht empfohlen für die Produktion aufgrund der Auswirkungen auf die Leistung).
Leistungsbeeinflussung:
- Höhere TTL = Bessere Leistung, aber langsamer, um Änderungen an ipsets widerzuspiegeln
- Niedrigere TTL = Reagiert schneller auf Änderungen an ipsets, aber mehr Kernelaufrufe
- Empfohlen: 30s bis 5m für die meisten Anwendungsfälle
ipset_fail_open on|off
Kontext: http, server
Standard: off
Steuert das Verhalten, wenn ein ipset-Lookup fehlschlägt (z. B. Set existiert nicht).
ipset_fail_open off; # Verweigern bei Fehler (sicher, Standard)
ipset_fail_open on; # Erlauben bei Fehler (verfügbar, aber riskant)
ipset_dryrun on|off
Kontext: http, server
Standard: off
Wenn aktiviert, protokolliert es, was blockiert werden würde, blockiert jedoch tatsächlich nicht. Perfekt zum Testen neuer Regeln in der Produktion.
ipset_dryrun on; # Protokollieren, aber nicht blockieren
Überprüfen Sie die Protokolle auf Nachrichten wie:
ipset: DRYRUN würde 1.2.3.4 blockieren (übereinstimmend: bad_guys)
Wichtig: Bei Verwendung der Variablen $ipset_result und $ipset_matched_set im Trockenlaufmodus spiegeln diese Werte den Zeitpunkt wider, zu dem die Anfrage verarbeitet wurde – nicht den aktuellen Zustand des ipsets. Wenn Sie das ipset später manuell überprüfen und die IP nicht finden, können mögliche Gründe sein:
- Timeout-Ablauf: Die IP wurde mit einem Timeout hinzugefügt (z. B.
timeout=86400) und ist inzwischen abgelaufen - Cache-Verzögerung: Das Modul speichert Lookup-Ergebnisse im Cache (Standard 60s). Ein Eintrag, der aus dem ipset entfernt wurde, kann weiterhin als "übereinstimmend" angezeigt werden, bis der Cache abläuft
- Manuelle Entfernung: Jemand oder etwas (fail2ban, Skripte) hat den Eintrag entfernt
Dies ist das erwartete Verhalten – der Trockenlauf zeigt Ihnen genau, was die Produktion zum Zeitpunkt der Anfrage sehen würde.
Ratenbegrenzung
ipset_ratelimit parameters
Kontext: http, server
Standard: —
Begrenzt Anfragen pro IP innerhalb eines Zeitfensters. Kann automatisch Verstöße zu einem ipset hinzufügen.
Parameter:
| Parameter | Erforderlich | Beschreibung |
|---|---|---|
rate=N |
Ja | Maximale Anfragen pro Fenster |
window=TIME |
Nein | Zeitfenster (Standard: 60s) |
autoban=SET |
Nein | ipset, um Verstöße hinzuzufügen |
ban_time=N |
Nein | Sekunden bis zur automatischen Ablauffrist (Standard: 3600) |
Beispiele:
## Grundlegend: 100 Anfragen pro Minute
ipset_ratelimit rate=100;
## Mit benutzerdefiniertem Fenster: 1000 Anfragen pro Stunde
ipset_ratelimit rate=1000 window=1h;
## Mit Auto-Ban: Fügen Sie Verstöße für 30 Minuten zu ipset hinzu
ipset_ratelimit rate=60 window=1m autoban=ratelimited ban_time=1800;
## Strenge API-Schutz
ipset_ratelimit rate=10 window=1s autoban=api_abusers ban_time=3600;
So funktioniert es:
1. Jede IP erhält einen Anfragezähler und einen Startzeitpunkt für das Fenster
2. Der Zähler erhöht sich bei jeder Anfrage
3. Wenn das Fenster abläuft, wird der Zähler zurückgesetzt
4. Wenn der Zähler rate überschreitet, wird 429 Too Many Requests zurückgegeben
5. Wenn autoban gesetzt ist, wird die IP dem angegebenen ipset hinzugefügt
Hinweis: Der Zustand der Ratenbegrenzung wird im gemeinsamen Speicher gespeichert und überlebt Neustarts der Worker.
JavaScript-Herausforderung
ipset_challenge on|off
Kontext: http, server
Standard: off
Aktiviert den JavaScript-Herausforderungsmodus. Browser müssen ein Proof-of-Work-Puzzle lösen, um auf die Website zuzugreifen. Effektiv gegen automatisierte Bots und Scraper.
ipset_challenge on;
So funktioniert es:
1. Die erste Anfrage erhält eine Herausforderungsseite (HTTP 503)
2. Der Browser führt JavaScript aus, das ein Hash-Puzzle löst
3. Die Lösung wird in einem Cookie (_ipset_verified) gespeichert
4. Nachfolgende Anfragen mit gültigem Cookie passieren
5. Das Cookie läuft nach 24 Stunden ab
ipset_challenge_difficulty level
Kontext: http, server
Standard: 2
Steuert die Schwierigkeit der Herausforderung (1-8). Höher = längere Lösungszeit.
| Level | Ungefährer Lösungszeit |
|---|---|
| 1 | ~100ms |
| 2 | ~500ms (Standard) |
| 3 | ~1 Sekunde |
| 4 | ~2 Sekunden |
| 5 | ~5 Sekunden |
| 6+ | ~10+ Sekunden |
ipset_challenge on;
ipset_challenge_difficulty 3; # ~1 Sekunde Lösungszeit
Merkmale der Herausforderungsseite: - Modernes, responsives Design - Animierter Ladeindikator - Fortschrittsfeedback - Automatische Weiterleitung bei Erfolg - Keine externen Abhängigkeiten
Honeypot Auto-Add
ipset_autoadd setname [timeout=seconds] [status=code]
Kontext: server, location
Standard: —
Fügt die Client-IP automatisch dem angegebenen ipset hinzu, wenn der Standort aufgerufen wird und einen HTTP-Statuscode zurückgibt. Perfekt für Honeypot-Fallen.
Parameter:
| Parameter | Erforderlich | Beschreibung |
|---|---|---|
| setname | Ja | Ziel-ipset-Name |
timeout=N |
Nein | Eintrags-Timeout in Sekunden |
status=N |
Nein | HTTP-Statuscode, der zurückgegeben werden soll (Standard: 404) |
Beispiele:
## Grundlegend: Zum Honeypot-Set hinzufügen und 404 zurückgeben (Standard)
location /config.php {
ipset_autoadd honeypot;
}
## Mit Timeout: Automatisches Ablaufen nach 24 Stunden
location /wp-admin.php {
ipset_autoadd scanners timeout=86400;
}
## 403 Forbidden anstelle von 404 zurückgeben
location /admin.php {
ipset_autoadd honeypot timeout=86400 status=403;
}
## 429 Zu viele Anfragen zurückgeben
location /api/hack {
ipset_autoadd abusers timeout=3600 status=429;
}
Häufige Honeypot-Pfade:
## WordPress-Fallen - gibt 404 zurück, um wie eine fehlende Datei auszusehen
location ~ ^/(wp-admin\.php|wp-login\.php|xmlrpc\.php)$ {
ipset_autoadd honeypot timeout=86400;
}
## Konfigurationsdatei-Fallen - gibt 403 zurück, um verbotenen Zugriff zu simulieren
location ~ ^/(\\.env|config\\.php|phpinfo\\.php)$ {
ipset_autoadd honeypot timeout=86400 status=403;
}
## Shell/Exploits-Fallen - schwerwiegend, blockieren für 1 Woche
location ~ ^/(shell|cmd|eval|exec)\\.php$ {
ipset_autoadd malicious timeout=604800 status=403;
}
Hinweis: Wenn eine IP automatisch hinzugefügt wird, gibt das Modul sofort den angegebenen HTTP-Statuscode (Standard 404) zurück, wodurch eine weitere Anforderungsverarbeitung verhindert wird. Das Keep-Alive der Verbindung wird ebenfalls deaktiviert, um weitere Anfragen über dieselbe Verbindung zu verhindern.
Beobachtbarkeit
ipset_stats
Kontext: location
Standard: —
Aktiviert den JSON-Statistik-Endpunkt.
location = /_stats {
ipset_stats;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Siehe JSON Stats API für das Antwortformat.
ipset_metrics
Kontext: location
Standard: —
Aktiviert den Prometheus-Metriken-Endpunkt.
location = /metrics {
ipset_metrics;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Siehe Prometheus Metrics für verfügbare Metriken.
📝 NGINX-Variablen
Das Modul stellt zwei Variablen für die Verwendung in Protokollen, Headern oder Bedingungen zur Verfügung.
$ipset_result
Die Zugriffsentscheidung, die für diese Anfrage getroffen wurde.
| Wert | Beschreibung |
|---|---|
allow |
Anfrage erlaubt |
deny |
Anfrage blockiert |
dryrun |
Würde blockiert werden (Trockenlaufmodus) |
ratelimited |
Ratenbegrenzung überschritten |
challenged |
Herausforderungsseite bereitgestellt |
$ipset_matched_set
Name des ipsets, das übereinstimmte (falls vorhanden). Leer, wenn keine Übereinstimmung vorliegt.
Hinweis: Diese Variable spiegelt den Übereinstimmungszustand zum Zeitpunkt der Anfrage wider, nicht den aktuellen Zustand des ipsets. Wenn Sie das ipset manuell überprüfen und die IP nicht finden: - Der Eintrag kann abgelaufen sein (ipsets unterstützen zeitabhängige Einträge) - Der Cache des Moduls (Standard 60s) zeigt möglicherweise einen kürzlich entfernten Eintrag weiterhin als übereinstimmend an - Etwas könnte den Eintrag nach der Verarbeitung der Anfrage entfernt haben
Anwendungsbeispiele
Benutzerdefiniertes Zugriffsprotokoll:
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'ipset_result="$ipset_result" '
'matched_set="$ipset_matched_set"';
access_log /var/log/nginx/security.log security;
Header für Debugging hinzufügen:
add_header X-IPSet-Result $ipset_result always;
add_header X-IPSet-Matched $ipset_matched_set always;
Bedingtes Protokollieren:
## Nur blockierte Anfragen protokollieren
map $ipset_result $loggable {
"deny" 1;
default 0;
}
access_log /var/log/nginx/blocked.log combined if=$loggable;
📊 Prometheus-Metriken
Der /metrics-Endpunkt gibt Metriken im Prometheus-Expositionsformat zurück.
Verfügbare Metriken
## HELP nginx_ipset_requests_total Gesamtzahl der verarbeiteten Anfragen
## TYPE nginx_ipset_requests_total counter
nginx_ipset_requests_total{result="checked"} 1234567
nginx_ipset_requests_total{result="allowed"} 1234000
nginx_ipset_requests_total{result="blocked"} 500
nginx_ipset_requests_total{result="error"} 67
## HELP nginx_ipset_cache_total Cache-Operationen
## TYPE nginx_ipset_cache_total counter
nginx_ipset_cache_total{result="hit"} 1200000
nginx_ipset_cache_total{result="miss"} 34567
## HELP nginx_ipset_cache_entries Aktuelle Cache-Einträge
## TYPE nginx_ipset_cache_entries gauge
nginx_ipset_cache_entries 5432
## HELP nginx_ipset_autoadd_total Auto-Add-Operationen
## TYPE nginx_ipset_autoadd_total counter
nginx_ipset_autoadd_total{result="success"} 42
nginx_ipset_autoadd_total{result="failed"} 3
## HELP nginx_ipset_ratelimit_total Ratenbegrenzungsereignisse
## TYPE nginx_ipset_ratelimit_total counter
nginx_ipset_ratelimit_total{action="triggered"} 156
nginx_ipset_ratelimit_total{action="autobanned"} 23
## HELP nginx_ipset_challenge_total Herausforderungsereignisse
## TYPE nginx_ipset_challenge_total counter
nginx_ipset_challenge_total{result="issued"} 1000
nginx_ipset_challenge_total{result="passed"} 950
nginx_ipset_challenge_total{result="failed"} 50
## HELP nginx_ipset_uptime_seconds Modul-Uptime
## TYPE nginx_ipset_uptime_seconds gauge
nginx_ipset_uptime_seconds 86400
Grafana-Dashboard-Abfragen
Anfragequote nach Ergebnis:
rate(nginx_ipset_requests_total[5m])
Blockierungsquote:
rate(nginx_ipset_requests_total{result="blocked"}[5m])
Cache-Trefferquote:
rate(nginx_ipset_cache_total{result="hit"}[5m]) /
(rate(nginx_ipset_cache_total{result="hit"}[5m]) + rate(nginx_ipset_cache_total{result="miss"}[5m]))
Ratenbegrenzungs-Auslöser pro Minute:
rate(nginx_ipset_ratelimit_total{action="triggered"}[1m]) * 60
📈 JSON Stats API
Der /_stats-Endpunkt gibt detaillierte Statistiken im JSON-Format zurück.
Antwortformat
{
"version": "2.0.7",
"uptime_seconds": 86400,
"requests": {
"checked": 1234567,
"allowed": 1234000,
"blocked": 500,
"errors": 67
},
"cache": {
"hits": 1200000,
"misses": 34567,
"entries": 5432,
"hit_rate": 97.20
},
"autoadd": {
"success": 42,
"failed": 3
},
"ratelimit": {
"triggered": 156,
"autobanned": 23
},
"challenge": {
"issued": 1000,
"passed": 950,
"failed": 50
}
}
Feldbeschreibungen
| Feld | Beschreibung |
|---|---|
version |
Modulversion |
uptime_seconds |
Sekunden seit dem Laden des Moduls |
requests.checked |
Gesamtzahl der verarbeiteten Anfragen |
requests.allowed |
Anfragen, die bestanden haben |
requests.blocked |
Anfragen, die blockiert wurden |
requests.errors |
ipset-Lookup-Fehler |
cache.hits |
Cache-Treffer (vermeidet Kernelaufruf) |
cache.misses |
Cache-Fehler (erforderte Kernelaufruf) |
cache.entries |
Aktuelle zwischengespeicherte Einträge |
cache.hit_rate |
Trefferquote in Prozent |
autoadd.success |
Erfolgreiche Honeypot-Hinzufügungen |
autoadd.failed |
Fehlgeschlagene Honeypot-Hinzufügungen |
ratelimit.triggered |
Verstöße gegen die Ratenbegrenzung |
ratelimit.autobanned |
IPs, die zur Sperrliste hinzugefügt wurden |
challenge.issued |
Herausforderungsseiten bereitgestellt |
challenge.passed |
Herausforderungen erfolgreich gelöst |
challenge.failed |
Herausforderungen fehlgeschlagen |
🏗️ Architektur
┌─────────────────────────────────────────────────────────────────────┐
│ ANFRAGEFLUSS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Eingehende Anfrage │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Ratenlimit │──── Überschreitet? ────▶ 429 + Auto-Ban │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ OK │
│ ▼ │
│ ┌───────────────┐ │
│ │ Herausforderung │──── Kein Cookie? ────▶ JS-Puzzle bereitstellen │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ Bestanden │
│ ▼ │
│ ┌───────────────┐ ┌─────────────┐ │
│ │ Cache-Überprüfung │────▶│ TREFFER │────▶ Verwenden Sie das zwischengespeicherte Ergebnis │
│ └───────┬───────┘ └─────────────┘ │
│ │ FEHLER │
│ ▼ │
│ ┌───────────────┐ │
│ │ ipset-Abfrage │──── Thread-lokale libipset-Sitzung │
│ │ (Kernel) │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Im Cache speichern│ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Entscheidung │──── Blacklist-Treffer? ────▶ Blockieren (403/444) │
│ │ │──── Whitelist-Fehler? ────▶ Blockieren (403/444) │
│ └───────┬───────┘ │
│ │ Erlauben │
│ ▼ │
│ ┌───────────────┐ │
│ │ Honeypot │──── Standort-Treffer? ────▶ Zum ipset hinzufügen │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ Fortfahren zu │
│ Inhaltsverarbeitung │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ GEMEINSAMER SPEICHER │
│ ┌────────────────┬─────────────────┬─────────────────────────────┐ │
│ │ Statistiken │ LRU-Cache │ Ratenlimit-Buckets │ │
│ │ (Zähler) │ (IP → Ergebnis) │ (IP → Anfragezähler) │ │
│ └────────────────┴─────────────────┴─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Speicherlayout
| Komponente | Ort | Zweck |
|---|---|---|
| libipset-Sitzung | Thread-lokal | Pro-Worker-Sitzung zur Vermeidung von Sperren |
| Lookup-Cache | Gemeinsamer Speicher | LRU-Cache von IP→Ergebnis-Zuordnungen |
| Ratenlimit-Buckets | Gemeinsamer Speicher | Pro-IP-Anfragezähler |
| Statistiken | Gemeinsamer Speicher | Atomare Zähler für Metriken |
📚 Beispiele
Beispiel 1: Grundlegende Blacklist
## Erstellen Sie ipset
sudo ipset create blacklist hash:ip
sudo ipset add blacklist 1.2.3.4
server {
listen 80;
ipset_blacklist blacklist;
location / {
root /var/www/html;
}
}
Beispiel 2: API mit Ratenbegrenzung
server {
listen 80;
# Strenge Ratenbegrenzung für API
ipset_ratelimit rate=100 window=1m autoban=api_banned ban_time=3600;
# Nur bekannte Partner erlauben
ipset_whitelist api_partners;
ipset_status 401;
location /api/ {
proxy_pass http://backend;
}
}
Beispiel 3: Vollständiger Sicherheitsstapel
server {
listen 80 default_server;
# Schicht 1: Bekannte Bedrohungen
ipset_blacklist malware_ips tor_exits datacenter_ranges;
ipset_status 444;
ipset_cache_ttl 5m;
# Schicht 2: Ratenbegrenzung
ipset_ratelimit rate=60 window=1m autoban=ratelimited ban_time=1800;
# Schicht 3: Bot-Herausforderung
ipset_challenge on;
ipset_challenge_difficulty 2;
# Echter Inhalt
location / {
root /var/www/html;
}
# Honeypot-Fallen - gibt 404 (Standard) zurück, um wie fehlende Dateien auszusehen
location ~ ^/(wp-admin|phpmyadmin|admin)\.php$ {
ipset_autoadd honeypot timeout=86400;
}
# Überwachung
location = /metrics {
ipset_metrics;
allow 10.0.0.0/8;
deny all;
}
}
Beispiel 4: Trockenlauf-Test
server {
listen 80;
# Testen Sie neue Regeln, ohne zu blockieren
ipset_blacklist new_threat_list;
ipset_dryrun on;
location / {
root /var/www/html;
}
}
Überprüfen Sie die Protokolle:
tail -f /var/log/nginx/error.log | grep "DRYRUN"
🔧 Fehlersuche
Modul wird nicht geladen
nginx: [emerg] dlopen() fehlgeschlagen
Lösung: Stellen Sie sicher, dass NGINX mit --with-compat kompiliert wurde und das Modul gegen dieselbe NGINX-Version kompiliert wurde.
ipset nicht gefunden
ipset: INVALID_SETNAME
Lösung: Erstellen Sie das ipset, bevor Sie NGINX starten:
sudo ipset create myset hash:ip
Berechtigung verweigert
ipset: Kernelfehler
Lösung: Der NGINX-Worker benötigt die Fähigkeit CAP_NET_ADMIN:
sudo setcap cap_net_admin+ep /usr/sbin/nginx
SELinux-Verweigerungen (RHEL/CentOS/AlmaLinux)
SELinux verhindert den Zugriff von /usr/sbin/nginx auf netlink_netfilter_socket
Lösung: Installieren Sie das enthaltene SELinux-Policy-Modul:
cd selinux/
sudo ./install.sh
Oder manuell:
## Überprüfen
semodule -l | grep nginx_ipset
Die Richtlinie erlaubt httpd_t (NGINX's SELinux-Domain) die Verwendung von netlink_netfilter-Sockets, die von libipset benötigt werden.
Hoher Speicherverbrauch
Lösung: Verringern Sie die Cache-TTL oder begrenzen Sie die Cache-Größe in der Konfiguration des gemeinsamen Speichers.
Ratenbegrenzung funktioniert nicht
Lösung: Stellen Sie sicher, dass das ipset für Auto-Ban existiert und Timeout-Unterstützung hat:
sudo ipset create ratelimited hash:ip timeout 3600
Protokoll zeigt "matched=setname", aber IP ist nicht im ipset
Dies ist das erwartete Verhalten. Das Modul berichtet, was es zum Zeitpunkt der Anfrage gesehen hat. Wenn Sie das ipset später überprüfen und die IP nicht finden:
-
Timeout-Ablauf: Die IP wurde mit einem Timeout hinzugefügt und ist inzwischen abgelaufen
# Überprüfen Sie, ob das Set Zeitüberschreitungen unterstützt ipset list setname | head -5 # Suchen Sie nach "timeout" in der Kopfzeile -
Modul-Cache: Das Modul speichert Lookups im Cache (Standard 60s). Eine kürzlich entfernte IP kann weiterhin als "übereinstimmend" angezeigt werden
# Cache vorübergehend für Debugging deaktivieren (nicht für die Produktion!) ipset_cache_ttl 0; -
Eintrag wurde entfernt: fail2ban, Skripte oder manuelle Befehle haben ihn möglicherweise entfernt
-
Konfigurationsproblem bei Fallen: Wenn Sie Honeypot-Fallen mit
ipset_autoaddverwenden, haben legitime Bots möglicherweise Fallen ausgelöst. Überprüfen Sie, ob Ihre Fallenstandorte nicht mit legitimen Bot-Pfaden (wie Sitemaps, robots.txt) überlappen. Verwenden Sierobots.txt, um Fallenpfade vom Crawlen auszuschließen.
autoadd schlägt mit "result=4" fehl
Das bedeutet, dass Sie timeout=N in ipset_autoadd verwenden, aber das ipset ohne Timeout-Unterstützung erstellt wurde.
Lösung: Erstellen Sie das ipset mit Timeout-Unterstützung neu:
## Verwenden von ipset direkt
sudo ipset destroy honeypot4
sudo ipset create honeypot4 hash:ip family inet timeout 86400
## Verwendung von firewall-cmd (RHEL/CentOS/Amazon Linux)
sudo firewall-cmd --permanent --delete-ipset=honeypot4
sudo firewall-cmd --permanent --new-ipset=honeypot4 --type=hash:ip \
--option=family=inet --option=timeout=86400
sudo firewall-cmd --reload
📋 Anforderungen
- NGINX ≥ 1.22 (gebaut mit
--with-compat) - Linux-Kernel mit ipset-Unterstützung (nf_tables oder xt_set-Modul)
- libipset-Bibliothek und Entwicklungsheader
- Fähigkeiten:
CAP_NET_ADMINfür ipset-Operationen
📜 Lizenz
Dies ist proprietäre Software. Alle Rechte vorbehalten.
Verfügbar ausschließlich über das GetPageSpeed Premium Repository.
👤 Autor
Danila Vershinin
GetPageSpeed LLC
🆘 Unterstützung
- Honeypot v2.0 Verwendung von ipset-access zum automatischen Sperren von Bots
- Unterstützung: Verfügbar für Premium-Abonnenten
- Kontakt: GetPageSpeed Support
NGINX IPSet Access Modul
Ein Premium-NGINX-Modul von GetPageSpeed LLC
www.getpagespeed.com