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_module.so;
Dieses Dokument beschreibt nginx-module-ipset-access v2.0.10, veröffentlicht am 13. Juni 2026.
Unternehmensgerechte IP-basierte Zugriffskontrolle für NGINX unter Verwendung von Linux ipset. Blockieren Sie Bedrohungen, begrenzen Sie Missbrauch, stellen Sie Herausforderungen für Bots 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.Plananforderung: Erfordert den Pro-Plan des GetPageSpeed NGINX Extras Abonnements.
✨ 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 von ipsets ohne NGINX neu zu laden |
| Benutzerdefinierte Statuscodes | Geben Sie jeden HTTP-Status beim Blockieren zurück |
Leistungsmerkmale
| Funktion | Beschreibung |
|---|---|
| Pro-Thread-Sitzungen | Thread-lokale libipset-Sitzungen beseitigen Sperrkonkurrenz |
| 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 Zeitfenstern |
| 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 aufrufen |
| Eingangszeitüberschreitung | Automatisches Ablaufen von Blacklist-Einträgen |
Betriebsmerkmale
| Funktion | Beschreibung |
|---|---|
| Trockenlaufmodus | Testen der Konfiguration ohne Blockierung |
| Fail-open/close | Steuerung des Verhaltens 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-Fallen-Liste
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 Folgendes 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-Abfragen im Cache gespeichert werden. Gecachte 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 gecachte Ergebnis läuft nach dem konfigurierten TTL ab. Für sofortige Effekte 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 von Leistungseinbußen).
Leistungsbeeinflussung:
- Höhere TTL = Bessere Leistung, aber langsameres Reflektieren von ipset-Änderungen
- Niedrigere TTL = Reaktionsschneller auf ipset-Änderungen, 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 eine ipset-Abfrage 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 für das 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: Wenn Sie die Variablen $ipset_result und $ipset_matched_set im Trockenlaufmodus verwenden, spiegeln diese Werte den Zeitpunkt wider, zu dem die Anfrage verarbeitet wurde - nicht den aktuellen Zustand des ipset. 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 cached Lookup-Ergebnisse (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 zur Anfragezeit sehen würde.
Ratenbegrenzung
ipset_ratelimit parameters
Kontext: http, server
Standard: —
Begrenzt Anfragen pro IP innerhalb eines Zeitfensters. Kann Verstöße automatisch 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;
Funktionsweise:
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 Worker-Neustarts.
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 Site zuzugreifen. Effektiv gegen automatisierte Bots und Scraper.
ipset_challenge on;
Funktionsweise:
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 Too Many Requests 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 Anfrageverarbeitung 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 zur 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 |
Ratenlimit überschritten |
challenged |
Herausforderungsseite bereitgestellt |
$ipset_matched_set
Name des ipset, 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 ipset. 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) kann einen kürzlich entfernten Eintrag weiterhin als übereinstimmend anzeigen. - Etwas könnte den Eintrag nach der Verarbeitung der Anfrage entfernt haben.
Verwendung Beispiele
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 Ratenlimit-Ereignisse
# 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])
Blockquote:
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]))
Ratenlimit-Auslösungen 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-Abfragefehler |
cache.hits |
Cache-Treffer (vermeidet Kernelaufruf) |
cache.misses |
Cache-Fehlversuche (erforderte Kernelaufrufe) |
cache.entries |
Aktuelle gecachte 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 automatisch zur Bannliste hinzugefügt wurden |
challenge.issued |
Herausforderungsseiten bereitgestellt |
challenge.passed |
Herausforderungen erfolgreich gelöst |
challenge.failed |
Herausforderungen fehlgeschlagen |
🏗️ Architektur
┌─────────────────────────────────────────────────────────────────────┐
│ ANFRAGEFLUSS │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Eingehende Anfrage │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Ratenlimit │──── Überschreitung? ────▶ 429 + Auto-Ban │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ OK │
│ ▼ │
│ ┌───────────────┐ │
│ │ Herausforderung │──── Kein Cookie? ────▶ JS-Puzzle bereitstellen │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ Bestanden │
│ ▼ │
│ ┌───────────────┐ ┌─────────────┐ │
│ │ Cache-Überprüfung │────▶│ TREFFER │────▶ Verwenden Sie das gecachte Ergebnis │
│ └───────┬───────┘ └─────────────┘ │
│ │ FEHLER │
│ ▼ │
│ ┌───────────────┐ │
│ │ ipset-Abfrage │──── Thread-lokale libipset-Sitzung │
│ │ (Kernel) │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Im Cache speichern│ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Entscheidung │──── Blacklist-Übereinstimmung? ────▶ Blockieren (403/444) │
│ │ │──── Whitelist-Fehlgeschlagen? ────▶ Blockieren (403/444) │
│ └───────┬───────┘ │
│ │ Erlauben │
│ ▼ │
│ ┌───────────────┐ │
│ │ Honeypot │──── Standortübereinstimmung? ────▶ Zum ipset hinzufügen │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ Fortfahren zu │
│ Inhalts-Handler │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ GEMEINSAMER SPEICHER │
│ ┌────────────────┬─────────────────┬─────────────────────────────┐ │
│ │ Statistiken │ LRU-Cache │ Ratenlimit-Buckets │ │
│ │ (Zähler) │ (IP → Ergebnis) │ (IP → Anfragezähler) │ │
│ └────────────────┴─────────────────┴─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Speicherlayout
| Komponente | Standort | Zweck |
|---|---|---|
| libipset-Sitzung | Thread-lokal | Pro-Arbeiter-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 Blockierung
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, dass /usr/sbin/nginx auf den netlink_netfilter_socket zugreift
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-Domäne), netlink_netfilter-Sockets zu verwenden, die von libipset benötigt werden.
firewalld + nftables-Backend + ipset: Quellen (Rocky/RHEL 9)
Wenn Sie firewalld mit dem Standard-nftables-Backend verwenden und versuchen, vom Modul verwaltete ipsets an Zonen anzuhängen mit:
firewall-cmd --permanent --zone=drop --add-source=ipset:honeypot4
firewall-cmd --reload
kann es beim Neuladen mit Fehlern wie:
COMMAND_FAILED: 'python-nftables' fehlgeschlagen: ... Fehler: Datei oder Verzeichnis nicht gefunden
fehlschlagen.
Grund (kurz): firewalld’s nftables-Backend verwendet nft sets für ipset:-Quellen, während dieses Modul Kernel-ipsets über libipset verwendet. Das sind unterschiedliche Subsysteme, die nicht zusammenarbeiten.
Empfehlung: Wenn Sie eine "drop before NGINX"-Firewall-Durchsetzung wünschen, die durch die automatischen Sperren dieses Moduls gesteuert wird, konfigurieren Sie firewalld, um das iptables-Backend zu verwenden:
sudo sed -i 's/^FirewallBackend=.*/FirewallBackend=iptables/' /etc/firewalld/firewalld.conf
sudo systemctl restart firewalld
sudo firewall-cmd --reload
Zukünftige Idee: Ein separates Modul, das mit nftables-Sets kommuniziert (z. B. "nfset-access"), könnte das nft-Backend von firewalld nativ unterstützen, würde jedoch nftables-Bibliotheken/APIs erfordern und liegt außerhalb des Rahmens dieses nur libipset-Moduls.
Hoher Speicherverbrauch
Lösung: Reduzieren 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 die automatische Sperre 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 meldet, 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, ob das Set Zeitüberschreitungen unterstützt ipset list setname | head -5 # Nach "timeout" in der Kopfzeile suchen -
Modul-Cache: Das Modul cached Lookups (Standard 60s). Eine kürzlich entfernte IP kann weiterhin als "übereinstimmend" angezeigt werden.
# Temporär Cache 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.
-
Fallen-Konfigurationsproblem: 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:
# Direkt mit ipset
sudo ipset destroy honeypot4
sudo ipset create honeypot4 hash:ip family inet timeout 86400
# Mit 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 (
ip_set+ netfilter/x_tables-Unterstützung; üblicherweise verfügbar auf RHEL/Rocky/Alma/Amazon Linux) - 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 für das automatische 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