Zum Inhalt

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.

Version GetPageSpeed

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

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

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

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

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

  4. Konfigurationsproblem bei Fallen: Wenn Sie Honeypot-Fallen mit ipset_autoadd verwenden, 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 Sie robots.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_ADMIN fü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

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