nftset-access: Null-Latenz-IP-Blockierung mit Linux-Kernel nftables-Sets
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-nftset-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-nftset-access
Aktivieren Sie das Modul, indem Sie Folgendes an den Anfang von /etc/nginx/nginx.conf hinzufügen:
load_module modules/ngx_http_nftset_access.so;
Dieses Dokument beschreibt nginx-module-nftset-access v3.0.0, veröffentlicht am 14. Februar 2026.
Unternehmensgerechte IP-basierte Zugriffskontrolle für NGINX unter Verwendung von Linux nftables-Sets. Blockieren Sie Bedrohungen, begrenzen Sie Missbrauch, stellen Sie Herausforderungen für Bots und schützen Sie Ihre Infrastruktur.
⚠️ Kommerzielle Software Dies ist ein proprietäres 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 Mitgliedschaft im nftables-Set |
| Mehrere Sets | Überprüfen gegen mehrere nft-Sets in einer Direktive |
| Live-Updates | Ändern Sie nft-Sets, ohne NGINX neu zu laden |
| Benutzerdefinierte Statuscodes | Geben Sie jeden HTTP-Status zurück, wenn blockiert |
| CIDR-Unterstützung | Verwenden Sie Intervall-Sets für Netzwerkbereiche (z.B. 192.168.1.0/24) |
Leistungsmerkmale
| Funktion | Beschreibung |
|---|---|
| Pro-Thread-Sitzungen | Thread-lokale libnftables-Kontexte 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ößen gegen die Ratenbegrenzung |
| JS-Herausforderung | Proof-of-Work-Herausforderung stoppt automatisierte Bots |
| Honeypot-Fallen | Automatisches Blacklisting von IPs, die Fallen-URLs aufrufen |
| Eintrag-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 nft-Set-Fehlern |
| Prometheus-Metriken | Native /metrics-Endpoint für Grafana |
| JSON-Statistiken | Detaillierte Statistik-API |
| NGINX-Variablen | $nftset_result und $nftset_matched_set |
🚀 Schnellstart
1. Erstellen Sie nftables-Sets
# Erstellen Sie eine Tabelle (falls nicht vorhanden)
sudo nft add table ip filter
# Erstellen Sie eine Blacklist mit Timeout-Unterstützung
sudo nft add set ip filter bad_guys '{ type ipv4_addr; flags timeout; timeout 1d; }'
# Erstellen Sie eine Ratenbegrenzungs-Sperrliste
sudo nft add set ip filter ratelimited '{ type ipv4_addr; flags timeout; timeout 30m; }'
# Erstellen Sie eine Honeypot-Fallenliste
sudo nft add set ip filter honeypot '{ type ipv4_addr; flags timeout; timeout 1d; }'
# Erstellen Sie eine Whitelist mit CIDR-Unterstützung
sudo nft add set ip filter trusted '{ type ipv4_addr; flags interval; }'
sudo nft add element ip filter trusted '{ 10.0.0.0/8, 192.168.0.0/16 }'
2. Konfigurieren Sie NGINX
load_module modules/ngx_http_nftset_access_module.so;
http {
server {
listen 80;
# Blockieren Sie bekannte schlechte IPs (Format: table:setname)
nftset_blacklist filter:bad_guys;
# Ratenbegrenzung: 100 Anfragen pro Minute
nftset_ratelimit rate=100 window=60s autoban=filter:ratelimited;
# Ihr Inhalt
location / {
root /var/www/html;
}
# Honeypot-Falle - gibt standardmäßig 404 zurück
location /wp-admin.php {
nftset_autoadd filter:honeypot timeout=86400;
}
# Metriken-Endpoint
location /metrics {
nftset_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-nftset-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_nftset_access_module.so;
Schritt 5: NGINX neu laden
sudo nginx -t && sudo systemctl reload nginx
📖 Konfigurationsreferenz
Set-Spezifikationsformat
Alle Direktiven, die auf nftables-Sets verweisen, verwenden das Format: table:setname
table— Der Name der nftables-Tabelle (z.B.filter,firewalld)setname— Der Set-Name innerhalb dieser Tabelle
Die IP-Familie (ip für IPv4, ip6 für IPv6) wird automatisch erkannt anhand der IP-Adresse des Clients.
Beispiele:
nftset_blacklist filter:blocklist; # IPv4-Client → ip filter blocklist
# IPv6-Client → ip6 filter blocklist
nftset_whitelist filter:trusted;
nftset_autoadd filter:honeypot timeout=3600;
Zugriffskontrolle
nftset_blacklist table:set1 [table:set2 ...]
Kontext: http, server
Standard: —
Blockiert Anfragen, wenn die Client-IP in irgendeinem der aufgeführten nft-Sets erscheint. Mehrere Sets werden der Reihe nach überprüft, bis ein Treffer gefunden wird.
# Einzelnes Set
nftset_blacklist filter:bad_guys;
# Mehrere Sets (ODER-Logik - blockiert, wenn in IRGENDEINEM Set)
nftset_blacklist filter:spammers filter:hackers filter:tor_exits;
# Deaktivieren
nftset_blacklist off;
nftset_whitelist table:set1 [table:set2 ...]
Kontext: http, server
Standard: —
Erlaubt Anfragen nur, wenn die Client-IP in mindestens einem der aufgeführten nft-Sets erscheint. Alle anderen IPs werden abgelehnt.
# Nur vertrauenswürdige IPs erlauben
nftset_whitelist filter:trusted_partners filter:office_ips;
Wichtig: Whitelisted IPs umgehen alle Modulbeschränkungen, einschließlich:
- Ratenbegrenzung (nftset_ratelimit)
- JavaScript-Herausforderungen (nftset_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
nftset_whitelist filter:admin_ips;
nftset_ratelimit rate=100 window=1m autoban=filter:ratelimited ban_time=1800;
nftset_challenge on;
nftset_status code
Kontext: http, server
Standard: 403
HTTP-Statuscode, der zurückgegeben wird, wenn eine Anfrage blockiert wird.
nftset_status 403; # Verboten (Standard)
nftset_status 444; # Verbindung ohne Antwort schließen (NGINX-Spezial)
nftset_status 429; # Zu viele Anfragen
nftset_status 503; # Dienst nicht verfügbar
Caching & Leistung
nftset_cache_ttl time
Kontext: http, server
Standard: 60s
Wie lange die Ergebnisse der nft-Set-Abfragen zwischengespeichert werden. Zwischengespeicherte Ergebnisse vermeiden wiederholte Kernelaufrufe für dieselbe IP.
nftset_cache_ttl 30s; # 30 Sekunden
nftset_cache_ttl 5m; # 5 Minuten
nftset_cache_ttl 1h; # 1 Stunde
Debugging-Hinweis: Wenn Sie eine IP aus einem nft-Set entfernen, aber das Modul sie weiterhin als "matched" 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 nftset_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 langsamer, um Änderungen an nft-Sets widerzuspiegeln
- Niedrigere TTL = Reaktionsschneller auf Änderungen an nft-Sets, aber mehr Kernelaufrufe
- Empfohlen: 30s bis 5m für die meisten Anwendungsfälle
nftset_fail_open on|off
Kontext: http, server
Standard: off
Steuert das Verhalten, wenn eine nft-Set-Abfrage fehlschlägt (z.B. Set existiert nicht).
nftset_fail_open off; # Verweigern bei Fehler (sicher, Standard)
nftset_fail_open on; # Erlauben bei Fehler (verfügbar, aber riskant)
nftset_dryrun on|off
Kontext: http, server
Standard: off
Wenn aktiviert, protokolliert, was blockiert werden würde, blockiert aber tatsächlich nicht. Perfekt zum Testen neuer Regeln in der Produktion.
nftset_dryrun on; # Protokollieren, aber nicht blockieren
Überprüfen Sie die Protokolle auf Nachrichten wie:
nftset: DRYRUN würde 1.2.3.4 blockieren (matched: filter:bad_guys)
Wichtig: Wenn Sie die Variablen $nftset_result und $nftset_matched_set im Trockenlaufmodus verwenden, spiegeln diese Werte den Zeitpunkt wider, zu dem die Anfrage verarbeitet wurde – nicht den aktuellen Zustand des nft-Sets. Wenn Sie das nft-Set 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 1d) und ist inzwischen abgelaufen. - Cache-Verzögerung: Das Modul speichert Abfrageergebnisse im Cache (Standard 60s). Ein Eintrag, der aus dem nft-Set entfernt wurde, kann weiterhin als "matched" 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
nftset_ratelimit parameters
Kontext: http, server
Standard: —
Begrenzt Anfragen pro IP innerhalb eines Zeitfensters. Kann automatisch Verstöße zu einem nft-Set hinzufügen.
Parameter:
| Parameter | Erforderlich | Beschreibung |
|---|---|---|
rate=N |
Ja | Maximale Anfragen pro Fenster |
window=TIME |
Nein | Zeitfenster (Standard: 60s) |
autoban=TABLE:SET |
Nein | nft-Set, um Verstöße hinzuzufügen |
ban_time=N |
Nein | Sekunden bis zum automatischen Ablauf (Standard: 3600) |
Beispiele:
# Grundlegend: 100 Anfragen pro Minute
nftset_ratelimit rate=100;
# Mit benutzerdefiniertem Fenster: 1000 Anfragen pro Stunde
nftset_ratelimit rate=1000 window=1h;
# Mit Auto-Ban: Fügt Verstöße für 30 Minuten zum nft-Set hinzu
nftset_ratelimit rate=60 window=1m autoban=filter:ratelimited ban_time=1800;
# Strenge API-Schutz
nftset_ratelimit rate=10 window=1s autoban=filter: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 zum angegebenen nft-Set hinzugefügt.
Hinweis: Der Zustand der Ratenbegrenzung wird im gemeinsamen Speicher gespeichert und überlebt Neustarts der Worker.
JavaScript-Herausforderung
nftset_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.
nftset_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 (_nftset_verified) gespeichert.
4. Nachfolgende Anfragen mit gültigem Cookie passieren.
5. Das Cookie läuft nach 24 Stunden ab.
nftset_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 |
nftset_challenge on;
nftset_challenge_difficulty 3; # ~1 Sekunde Lösungszeit
Herausforderungsseitenfunktionen: - Modernes, responsives Design - Animierter Ladeindikator - Fortschrittsfeedback - Automatische Weiterleitung bei Erfolg - Keine externen Abhängigkeiten
Honeypot Auto-Add
nftset_autoadd table:setname [table:setname2 ...] [timeout=seconds] [status=code]
Kontext: server, location
Standard: —
Fügt die Client-IP automatisch zu den angegebenen nft-Sets hinzu, wenn die Location aufgerufen wird und gibt einen HTTP-Statuscode zurück. Perfekt für Honeypot-Fallen.
Parameter:
| Parameter | Erforderlich | Beschreibung |
|---|---|---|
| table:setname | Ja | Ziel-nft-Set (kann mehrere angeben) |
timeout=N |
Nein | Eintrag-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 {
nftset_autoadd filter:honeypot;
}
# Mit Timeout: Automatisches Ablaufen nach 24 Stunden
location /wp-admin.php {
nftset_autoadd filter:scanners timeout=86400;
}
# 403 Forbidden anstelle von 404 zurückgeben
location /admin.php {
nftset_autoadd filter:honeypot timeout=86400 status=403;
}
# Zu mehreren Sets hinzufügen (IPv4 und IPv6)
location /trap {
nftset_autoadd filter:honeypot4 filter:honeypot6 timeout=86400;
}
Häufige Honeypot-Pfade:
# WordPress-Fallen - geben Sie 404 zurück, um wie eine fehlende Datei auszusehen
location ~ ^/(wp-admin\.php|wp-login\.php|xmlrpc\.php)$ {
nftset_autoadd filter:honeypot timeout=86400;
}
# Konfigurationsdateifallen - geben Sie 403 zurück, um verbotenen Zugriff zu simulieren
location ~ ^/(\.env|config\.php|phpinfo\.php)$ {
nftset_autoadd filter:honeypot timeout=86400 status=403;
}
# Shell/Exploits-Fallen - schwerwiegend, blockieren für 1 Woche
location ~ ^/(shell|cmd|eval|exec)\.php$ {
nftset_autoadd filter: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 und verhindert eine weitere Anfrageverarbeitung. Das Keep-Alive der Verbindung wird ebenfalls deaktiviert, um weitere Anfragen über dieselbe Verbindung zu verhindern.
Beobachtbarkeit
nftset_stats
Kontext: location
Standard: —
Aktiviert den JSON-Statistik-Endpoint.
location = /_stats {
nftset_stats;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Siehe JSON Stats API für das Antwortformat.
nftset_metrics
Kontext: location
Standard: —
Aktiviert den Prometheus-Metriken-Endpoint.
location = /metrics {
nftset_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.
$nftset_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 serviert |
$nftset_matched_set
Name des nft-Sets, das übereinstimmte (falls vorhanden), im Format table:setname. Leer, wenn keine Übereinstimmung.
Hinweis: Diese Variable spiegelt den Übereinstimmungszustand zum Zeitpunkt der Anfrage wider, nicht den aktuellen Zustand des nft-Sets. Wenn Sie das nft-Set manuell überprüfen und die IP nicht finden: - Der Eintrag kann abgelaufen sein (nft-Sets 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.
Anwendungsbeispiele
Benutzerdefiniertes Zugriffsprotokoll:
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'nftset_result="$nftset_result" '
'matched_set="$nftset_matched_set"';
access_log /var/log/nginx/security.log security;
Header für Debugging hinzufügen:
add_header X-NFTSet-Result $nftset_result always;
add_header X-NFTSet-Matched $nftset_matched_set always;
Bedingtes Protokollieren:
# Nur blockierte Anfragen protokollieren
map $nftset_result $loggable {
"deny" 1;
default 0;
}
access_log /var/log/nginx/blocked.log combined if=$loggable;
📊 Prometheus-Metriken
Der /metrics-Endpoint gibt Metriken im Prometheus-Expositionsformat zurück.
Verfügbare Metriken
# HELP nginx_nftset_requests_total Gesamtanzahl der verarbeiteten Anfragen
# TYPE nginx_nftset_requests_total counter
nginx_nftset_requests_total{result="checked"} 1234567
nginx_nftset_requests_total{result="allowed"} 1234000
nginx_nftset_requests_total{result="blocked"} 500
nginx_nftset_requests_total{result="error"} 67
# HELP nginx_nftset_cache_total Cache-Operationen
# TYPE nginx_nftset_cache_total counter
nginx_nftset_cache_total{result="hit"} 1200000
nginx_nftset_cache_total{result="miss"} 34567
# HELP nginx_nftset_cache_entries Aktuelle Cache-Einträge
# TYPE nginx_nftset_cache_entries gauge
nginx_nftset_cache_entries 5432
# HELP nginx_nftset_autoadd_total Auto-Add-Operationen
# TYPE nginx_nftset_autoadd_total counter
nginx_nftset_autoadd_total{result="success"} 42
nginx_nftset_autoadd_total{result="failed"} 3
# HELP nginx_nftset_ratelimit_total Ratenlimit-Ereignisse
# TYPE nginx_nftset_ratelimit_total counter
nginx_nftset_ratelimit_total{action="triggered"} 156
nginx_nftset_ratelimit_total{action="autobanned"} 23
# HELP nginx_nftset_challenge_total Herausforderungsereignisse
# TYPE nginx_nftset_challenge_total counter
nginx_nftset_challenge_total{result="issued"} 1000
nginx_nftset_challenge_total{result="passed"} 950
nginx_nftset_challenge_total{result="failed"} 50
# HELP nginx_nftset_uptime_seconds Modul-Uptime
# TYPE nginx_nftset_uptime_seconds gauge
nginx_nftset_uptime_seconds 86400
Grafana-Dashboard-Abfragen
Anfragequote nach Ergebnis:
rate(nginx_nftset_requests_total[5m])
Blockquote:
rate(nginx_nftset_requests_total{result="blocked"}[5m])
Cache-Trefferquote:
rate(nginx_nftset_cache_total{result="hit"}[5m]) /
(rate(nginx_nftset_cache_total{result="hit"}[5m]) + rate(nginx_nftset_cache_total{result="miss"}[5m]))
Ratenlimit-Auslöser pro Minute:
rate(nginx_nftset_ratelimit_total{action="triggered"}[1m]) * 60
📈 JSON Stats API
Der /_stats-Endpoint gibt detaillierte Statistiken im JSON-Format zurück.
Antwortformat
{
"version": "3.0.0",
"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 |
Gesamtanzahl der verarbeiteten Anfragen |
requests.allowed |
Anfragen, die bestanden haben |
requests.blocked |
Anfragen, die blockiert wurden |
requests.errors |
Fehler bei der nft-Set-Abfrage |
cache.hits |
Cache-Treffer (vermeidet Kernelaufruf) |
cache.misses |
Cache-Fehlversuche (benötigter 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 automatisch zur Sperrliste hinzugefügt wurden |
challenge.issued |
Herausforderungsseiten serviert |
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 servieren │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ Bestanden │
│ ▼ │
│ ┌───────────────┐ ┌─────────────┐ │
│ │ Cache-Überprüfung │────▶│ TREFFER │────▶ Verwenden Sie das zwischengespeicherte Ergebnis │
│ └───────┬───────┘ └─────────────┘ │
│ │ FEHLER │
│ ▼ │
│ ┌───────────────┐ │
│ │ nft-Abfrage │──── Thread-lokaler libnftables-Kontext │
│ │ (Kernel) │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Im Cache speichern│ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Entscheidung │──── Blacklist-Treffer? ────▶ Blockieren (403/444) │
│ │ │──── Whitelist-Fehlgriff? ────▶ Blockieren (403/444) │
│ └───────┬───────┘ │
│ │ Erlauben │
│ ▼ │
│ ┌───────────────┐ │
│ │ Honeypot │──── Standorttreffer? ────▶ Zum nft-Set hinzufügen │
│ │ Überprüfung │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ Weiter zu │
│ Inhaltsverarbeiter │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ GEMEINSAMER SPEICHER │
│ ┌────────────────┬─────────────────┬─────────────────────────────┐ │
│ │ Statistiken │ LRU-Cache │ Ratenlimit-Eimer │ │
│ │ (Zähler) │ (IP → Ergebnis) │ (IP → Anfragezähler) │ │
│ └────────────────┴─────────────────┴─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Speicherlayout
| Komponente | Standort | Zweck |
|---|---|---|
| libnftables-Kontext | Thread-lokal | Per-Worker-Kontext zur Vermeidung von Sperren |
| Lookup-Cache | Gemeinsamer Speicher | LRU-Cache von IP→Ergebnis-Zuordnungen |
| Ratenlimit-Eimer | Gemeinsamer Speicher | Anfragezähler pro IP |
| Statistiken | Gemeinsamer Speicher | Atomare Zähler für Metriken |
📚 Beispiele
Beispiel 1: Grundlegende Blacklist
# Erstellen Sie nft-Tabelle und -Set
sudo nft add table ip filter
sudo nft add set ip filter blacklist '{ type ipv4_addr; }'
sudo nft add element ip filter blacklist '{ 1.2.3.4 }'
server {
listen 80;
nftset_blacklist filter:blacklist;
location / {
root /var/www/html;
}
}
Beispiel 2: API mit Ratenbegrenzung
server {
listen 80;
# Strenge Ratenbegrenzung für API
nftset_ratelimit rate=100 window=1m autoban=filter:api_banned ban_time=3600;
# Nur bekannte Partner erlauben
nftset_whitelist filter:api_partners;
nftset_status 401;
location /api/ {
proxy_pass http://backend;
}
}
Beispiel 3: Vollständiger Sicherheitsstapel
server {
listen 80 default_server;
# Ebene 1: Bekannte Bedrohungen
nftset_blacklist filter:malware_ips filter:tor_exits filter:datacenter_ranges;
nftset_status 444;
nftset_cache_ttl 5m;
# Ebene 2: Ratenbegrenzung
nftset_ratelimit rate=60 window=1m autoban=filter:ratelimited ban_time=1800;
# Ebene 3: Bot-Herausforderung
nftset_challenge on;
nftset_challenge_difficulty 2;
# Echte Inhalte
location / {
root /var/www/html;
}
# Honeypot-Fallen - geben Sie 404 (Standard) zurück, um wie fehlende Dateien auszusehen
location ~ ^/(wp-admin|phpmyadmin|admin)\.php$ {
nftset_autoadd filter:honeypot timeout=86400;
}
# Überwachung
location = /metrics {
nftset_metrics;
allow 10.0.0.0/8;
deny all;
}
}
Beispiel 4: Trockenlauf-Test
server {
listen 80;
# Testen Sie neue Regeln, ohne zu blockieren
nftset_blacklist filter:new_threat_list;
nftset_dryrun on;
location / {
root /var/www/html;
}
}
Überprüfen Sie die Protokolle:
tail -f /var/log/nginx/error.log | grep "DRYRUN"
Beispiel 5: CIDR-Whitelist (Netzwerkbereiche)
# Erstellen Sie Intervall-Set für CIDR-Bereiche
sudo nft add table ip filter
sudo nft add set ip filter trusted '{ type ipv4_addr; flags interval; }'
sudo nft add element ip filter trusted '{ 192.168.1.0/24, 10.0.0.0/8 }'
# IPv6-Version
sudo nft add table ip6 filter
sudo nft add set ip6 filter trusted6 '{ type ipv6_addr; flags interval; }'
sudo nft add element ip6 filter trusted6 '{ 2001:db8::/32 }'
server {
listen 80;
# Ganze Netzwerke whitelisten
nftset_whitelist filter:trusted;
location / {
root /var/www/html;
}
}
🔧 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.
nft-Set nicht gefunden
nftset: set 'filter:myset' existiert nicht
Lösung: Erstellen Sie die nft-Tabelle und das Set, bevor Sie NGINX starten:
sudo nft add table ip filter
sudo nft add set ip filter myset '{ type ipv4_addr; }'
TIPP: Listen Sie verfügbare Sets auf mit:
nft list sets
Berechtigung verweigert
nftset: 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 netlink_netfilter_socket verwendet
Lösung: Installieren Sie das enthaltene SELinux-Policy-Modul:
cd selinux/
sudo ./install.sh
Oder manuell:
# Überprüfen
semodule -l | grep nginx_nftset
Die Richtlinie erlaubt httpd_t (NGINX's SELinux-Domain), die netlink_netfilter-Sockets zu verwenden, die von libnftables benötigt werden.
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 nft-Set für Auto-Ban existiert und Timeout-Unterstützung hat:
sudo nft add table ip filter
sudo nft add set ip filter ratelimited '{ type ipv4_addr; flags timeout; timeout 1h; }'
Protokoll zeigt "matched=table:setname", aber IP ist nicht im nft-Set
Dies ist das erwartete Verhalten. Das Modul berichtet, was es zum Zeitpunkt der Anfrage gesehen hat. Wenn Sie das nft-Set 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 die Set-Flags nft list set ip filter setname # Suchen Sie nach "flags timeout" in der Ausgabe -
Modul-Cache: Das Modul speichert Abfragen im Cache (Standard 60s). Eine kürzlich entfernte IP kann weiterhin als "matched" angezeigt werden.
# Cache vorübergehend für Debugging deaktivieren (nicht für die Produktion!) nftset_cache_ttl 0; -
Eintrag wurde entfernt: fail2ban, Skripte oder manuelle Befehle haben ihn möglicherweise entfernt.
-
Problem mit der Fallen-Konfiguration: Wenn Sie Honeypot-Fallen mit
nftset_autoaddverwenden, könnten legitime Bots Fallen ausgelöst haben. Ü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 Timeout-Fehler fehl
Das bedeutet, dass Sie timeout=N in nftset_autoadd verwenden, aber das nft-Set ohne Timeout-Unterstützung erstellt wurde.
Lösung: Erstellen Sie das nft-Set mit Timeout-Unterstützung neu:
# Löschen und mit Timeout-Flag neu erstellen
sudo nft delete set ip filter honeypot
sudo nft add set ip filter honeypot '{ type ipv4_addr; flags timeout; timeout 1d; }'
🔄 Migration von ipset-access
Wenn Sie von dem älteren ngx_http_ipset_access_module migrieren, befolgen Sie diese Schritte:
1. Konvertieren Sie ipsets in nft-Sets
# Altes ipset
ipset create bad_guys hash:ip timeout 86400
# Neues nft-Set-Äquivalent
nft add table ip filter
nft add set ip filter bad_guys '{ type ipv4_addr; flags timeout; timeout 1d; }'
# Für CIDR-Bereiche (hash:net → Intervall-Flag)
# Alt: ipset create networks hash:net
# Neu:
nft add set ip filter networks '{ type ipv4_addr; flags interval; }'
2. Aktualisieren Sie die NGINX-Konfiguration
| Alt (ipset) | Neu (nftset) |
|---|---|
ipset_blacklist bad_guys; |
nftset_blacklist filter:bad_guys; |
ipset_whitelist trusted; |
nftset_whitelist filter:trusted; |
ipset_autoadd honeypot timeout=3600; |
nftset_autoadd filter:honeypot timeout=3600; |
ipset_ratelimit rate=100 autoban=ratelimited; |
nftset_ratelimit rate=100 autoban=filter:ratelimited; |
ipset_challenge on; |
nftset_challenge on; |
ipset_challenge_difficulty 3; |
nftset_challenge_difficulty 3; |
ipset_dryrun on; |
nftset_dryrun on; |
ipset_fail_open on; |
nftset_fail_open on; |
ipset_cache_ttl 60s; |
nftset_cache_ttl 60s; |
ipset_status 403; |
nftset_status 403; |
ipset_stats; |
nftset_stats; |
ipset_metrics; |
nftset_metrics; |
$ipset_result |
$nftset_result |
$ipset_matched_set |
$nftset_matched_set |
3. Aktualisieren Sie die Protokollformate
# Alt
log_format security '... ipset_result="$ipset_result" matched_set="$ipset_matched_set"';
# Neu
log_format security '... nftset_result="$nftset_result" matched_set="$nftset_matched_set"';
4. Aktualisieren Sie Prometheus/Grafana-Abfragen
| Alte Metrik | Neue Metrik |
|---|---|
nginx_ipset_requests_total |
nginx_nftset_requests_total |
nginx_ipset_cache_total |
nginx_nftset_cache_total |
nginx_ipset_cache_entries |
nginx_nftset_cache_entries |
nginx_ipset_autoadd_total |
nginx_nftset_autoadd_total |
nginx_ipset_ratelimit_total |
nginx_nftset_ratelimit_total |
nginx_ipset_challenge_total |
nginx_nftset_challenge_total |
nginx_ipset_uptime_seconds |
nginx_nftset_uptime_seconds |
5. Wichtige Unterschiede
| Funktion | ipset-access | nftset-access |
|---|---|---|
| Backend | libipset (Kernel-ipsets) | libnftables (nftables) |
| Set-Format | setname |
table:setname |
| CIDR-Sets | hash:net-Typ |
flags interval |
| Familie | Im Set-Typ angegeben | Automatisch erkannt von der Client-IP |
| firewalld | Nur iptables-Backend | nftables-Backend-kompatibel |
Warum migrieren?
- RHEL 9/Rocky 9-Kompatibilität: firewalld verwendet standardmäßig das nftables-Backend.
- Moderne Kernelunterstützung: nftables ist die Zukunft der Linux-Firewalls.
- Einheitliche Verwaltung: Verwenden Sie
nft-Befehle sowohl für Firewall- als auch für Zugriffskontrolle. - Bessere CIDR-Unterstützung: Intervall-Sets verwalten Netzwerkbereiche effizient.
📋 Anforderungen
- NGINX ≥ 1.22 (gebaut mit
--with-compat) - Linux-Kernel mit nftables-Unterstützung
- libnftables-Bibliothek und Entwicklungsheader
- Fähigkeiten:
CAP_NET_ADMINfür nftables-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 nftset-access zum automatischen Sperren von Bots
- Unterstützung: Verfügbar für Premium-Abonnenten
- Kontakt: GetPageSpeed Support
NGINX NFTSet Access Modul
Ein Premium-NGINX-Modul von GetPageSpeed LLC
www.getpagespeed.com