Zum Inhalt

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.

Version GetPageSpeed

⚠️ 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:

  1. Timeout-Ablauf: Die IP wurde mit einem Timeout hinzugefügt (z.B. timeout 1d) und ist inzwischen abgelaufen.
  2. 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.
  3. 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:

  1. 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
    

  2. 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;
    

  3. Eintrag wurde entfernt: fail2ban, Skripte oder manuelle Befehle haben ihn möglicherweise entfernt.

  4. Problem mit der Fallen-Konfiguration: Wenn Sie Honeypot-Fallen mit nftset_autoadd verwenden, 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 Sie robots.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_ADMIN fü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

NGINX NFTSet Access Modul
Ein Premium-NGINX-Modul von GetPageSpeed LLC
www.getpagespeed.com