abuse-guard: Automatisches Sperren missbräuchlicher Clients anhand der Fehlerantwortrate
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-abuse-guard
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-abuse-guard
Aktivieren Sie das Modul, indem Sie Folgendes am Anfang von /etc/nginx/nginx.conf hinzufügen:
load_module modules/ngx_http_abuse_guard_module.so;
Dieses Dokument beschreibt nginx-module-abuse-guard v2.1.0, veröffentlicht am 03. September 2026.
Ihr Fehlerprotokoll ist ein Geständnis. Abuse Guard liest es in Echtzeit und sperrt Missbraucher aus.
Jeder Scanner, Fuzzer und Credential-Stuffing-Bot hinterlässt denselben Fingerabdruck:
eine Salve von 404s auf der Suche nach versteckten Pfaden, 403s, die an verschlossenen Türen rütteln, fehlgeschlagene Anfrage um fehlgeschlagene Anfrage. Abuse Guard beobachtet die Statuscodes, die Ihr Server tatsächlich zurückgibt, identifiziert die Clients, deren Datenverkehr überwiegend aus Fehlern besteht, und sperrt sie aus — entschieden innerhalb des NGINX-Workers, bei der Anfrage selbst, in wenigen Mikrosekunden. Kein Sidecar. Kein Log-Shipper. Keine Skriptebene. Nur kompiliertes C, das eine Aufgabe außergewöhnlich gut erledigt.
Technische Daten
| Auslöser | Fehlerantwortrate pro Client Ihrer Wahl (standardmäßig 403/404) |
| Aktion | Zeitlich begrenzte Sperre — ein harter Bann für ein festes Zeitfenster, keine Drosselung |
| Entscheidungspunkt | NGINX-Preaccess-Phase, bevor ein Handler oder Upstream ausgeführt wird |
| Speichermodell | Feste Bytes pro Client, unabhängig vom Schwellenwert → Botnetz-tauglich |
| Fleet-Modus | Optionale Bann-Replikation über Knoten hinweg via Redis / Valkey |
| Dauerhaftigkeit | Optionale Exit-Snapshots erhalten aktive Sperren über Neustarts hinweg |
| Ressourcenverbrauch | Ein eigenständiges Modul; standardmäßig null Laufzeitabhängigkeiten |
| Plattformen | RHEL / AlmaLinux / Rocky / CentOS Stream / Oracle / Amazon Linux |
| ## |
Das Problem, das es beseitigt
Legitime Besucher erzeugen fast nie einen Ausbruch von Fehlern. Missbraucher erzeugen kaum etwas anderes — diese Asymmetrie ist das ganze Spiel. Ein Schwachstellenscanner, der Ihren Verzeichnisbaum durchläuft, ist eine Wand aus 404s. Ein Bot, der Admin-Endpunkte abklopft, ist eine Wand aus 403s. Ein Brute-Force-Lauf ist eine Wand aus Fehlern.
Ratenbegrenzer behandeln diesen Datenverkehr wie jeden anderen: Sie verlangsamen alle nach Anfragevolumen und lassen den Übeltäter sofort wieder herein, sobald er nachlässt. Abuse Guard macht das Gegenteil. Es ignoriert wohlverhaltenen Datenverkehr vollständig und reserviert seine eine Antwort — einen echten, zeitlich begrenzten Bann — für Clients, die durch ihre Fehler definiert sind.
Verwenden Sie einen Ratenbegrenzer, um Last zu formen. Verwenden Sie Abuse Guard, um Missbrauch zu entfernen.
Wie eine Sperre entschieden wird
Drei bewegliche Teile, alle innerhalb des Workers:
1 · Ein Leaky-Bucket-Score pro Client. Jede Client-Identität trägt eine einzelne kleine Zahl im gemeinsamen Speicher. Jeder passende Fehler fügt standardmäßig einen Punkt hinzu, oder das Gewicht, das Sie diesem Status zuweisen; der Score sickert kontinuierlich mit threshold ÷ interval pro Sekunde ab. Ein kurzer, scharfer Ausbruch treibt ihn über die Grenze; ein langsames Tröpfeln niemals. Entscheidend ist, dass dieser Score ein Datensatz fester Größe ist, egal wie hoch Sie den Schwellenwert setzen, sodass eine einzelne Zone die Zehntausende verschiedener Quelladressen, die ein Botnetz auf Sie wirft, problemlos verfolgt.
2 · Eine harte Frist. In dem Moment, in dem der Score Ihren Schwellenwert überschreitet, erhält der Client einen blocked_until-Zeitstempel. Bis dahin ist er einfach weg — jede Anfrage wird in der Preaccess-Phase abgewiesen, bevor NGINX einen Zyklus für Routing, Dateien oder Upstreams aufwendet. Die Ablehnung ist das billigste mögliche Ergebnis.
3 · Eine datenschutzkorrekte Verweigerung. Gebannte Clients erhalten 429 Too Many Requests (Code Ihrer Wahl), gekennzeichnet, sodass kein gemeinsamer Cache es speichern und die Bestrafung eines Clients einem anderen ausliefern kann, mit einem Retry-After, der ehrlichen Clients mitteilt, wann sie zurückkehren sollen.
Identitäten werden in einen Digest fester Größe gefaltet, sodass die Schlüsselung auf etwas Großem wie $request_uri oder einem Header genau so viel Speicher kostet wie die Schlüsselung auf einer IP.
In unter einer Minute live
Abuse Guard wird als vorkompiliertes, signiertes Modul aus dem GetPageSpeed-Repository geliefert — einfügen, keine Build-Toolchain erforderlich.
sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
sudo yum -y install nginx-module-abuse-guard
Verdrahten Sie es:
load_module modules/ngx_http_abuse_guard_module.so;
http {
abuse_guard_zone zone=clients:10m; # eine Shared-Memory-Zone
server {
location / {
abuse_guard zone=clients; # hier durchsetzen
}
}
}
sudo nginx -t && sudo systemctl reload nginx
Diese Standardeinstellungen sperren jede IP, die 100 403/404-Antworten innerhalb eines 5-Minuten-Fensters zurückgibt, für eine Stunde. Sie können jede der folgenden Zahlen anpassen oder lockern.
Konfiguration
Abuse Guard besteht aus vier Direktiven. Die erste deklariert eine Richtlinie; die übrigen wenden sie an, befreien Personen von ihr und teilen sie (optional) maschinenübergreifend.
Eine Richtlinie deklarieren — abuse_guard_zone
Eine Direktive auf http-Ebene. Sie grenzt eine Shared-Memory-Zone ab und legt die Richtlinie fest, die sie regiert. Stellen Sie so viele oder wenige Regler ein, wie Sie möchten — Name und Größe der Zone sind das Einzige, was Sie angeben müssen; sinnvolle Standardwerte füllen den Rest aus (die unten gezeigten Werte sind genau diese Standardwerte).
abuse_guard_zone zone=clients:10m ← Name + Größe (das einzige Muss)
key=$binary_remote_addr ← wer ist "ein Client"
statuses=403,404 ← welche Antworten zum Score beitragen
interval=300s ← das Bewertungsfenster
threshold=100 ← Score in diesem Fenster → Bann
block=60m; ← wie lange der Bann gilt
zone=clients:10m ist die Identität und das Budget der Richtlinie: ein Name, auf den Sie von abuse_guard verweisen, und die Shared-Memory-Größe. Etwa 10 MB verfolgen in der Größenordnung von hunderttausend aktiven Clients.
Alles andere ist optionale Feinabstimmung:
key— der Ausdruck, der einen einzelnen Client definiert. Jede NGINX-Variable; der Standardwert$binary_remote_addrschlüsselt auf der Quell-IP auf. Eine Anfrage, deren Schlüssel leer ausgegeben wird, wird vollständig übersprungen (praktisch mit einermap, weiter unten).statuses— die Antworten, die zum Score beitragen. Ein bloßer Code oder Bereich hat Gewicht 1, wobei die ursprüngliche Syntax erhalten bleibt:statuses=403,404,500-599. Fügen Sie:weighthinzu, um eine Antwort mehr von demselben Budget verbrauchen zu lassen, z. B.statuses=404,401:5,500-599:2. Gewichte sind ganze Zahlen von 1 bis 1024, und ein Bereich wendet sein Gewicht auf jeden Status an, den er abdeckt. Das Wiederholen oder Überlappen eines Status mit demselben Gewicht ist harmlos; widersprüchliche Gewichte führen zu einem Fehler beinginx -t. Der Standardwert bleibt403,404.interval— das Fenster, über das der Score abklingt (Standardwert300s). Ein Ausbruch innerhalb davon löst einen Bann aus; ein langsames Tröpfchen, das sich weiter verteilt, akkumuliert nie.threshold— wie viele Score-Punkte innerhalb dieses Fensters die Grenze überschreiten, bis zu 1024 (Standardwert100). Eine schwere Antwort kann das verbleibende Budget verbrauchen und sofort einen Bann auslösen.block— wie lange ein ausgelöster Client gesperrt bleibt (Standardwert60m).inactive— wie lange ein ruhender Client im Speicher verbleibt, bevor er freigegeben wird (Standardwertmax(1h, interval, block); jeder explizite Wert muss mindestens so groß sein wie sowohlintervalals auchblock).redis—on, um die Sperren dieser Zone über einen Fleet hinweg zu replizieren (siehe unten); standardmäßigoff.persist— ein Dateipfad, in den aktive Sperren beim sauberen Worker-Exit geschrieben und beim Start geladen werden.persist_secret— bei Builds mit Unterstützung für signierte Snapshots ein Hex-Schlüssel, der HMAC-SHA256-Authentifizierung hinzufügt, sodass eine manipulierte Datei abgelehnt wird.
Warum
5xxstandardmäßig weggelassen wird: Ein Serverfehler ist normalerweise Ihre Seite, und das Zählen würde es einem fehlerhaften Backend ermöglichen, unschuldige Besucher sperren zu lassen. Fügen Siestatuses=403,404,500-599nur hinzu, wenn Sie bewusst auf Clients reagieren möchten, die Serverfehler auslösen.
Anwenden — abuse_guard
Gültig in http-, server- und location-Blöcken, sodass Sie eine ganze Website oder nur die Endpunkte schützen können, die Missbrauch anziehen. Benennen Sie die Zone, um sie zu aktivieren; schreiben Sie abuse_guard off; in einen verschachtelten Gültigkeitsbereich, um sie wieder zu deaktivieren.
location /wp-login.php {
abuse_guard zone=clients status=429 log_level=warn;
}
zone— die Zone (oben deklariert), deren Richtlinie hier gilt.status— der Code, den ein gebannter Client erhält, irgendwo in400–599(Standardwert429).dry_run—onzum Beobachten ohne Durchsetzung: Das Urteil wird protokolliert, aber kein Bann geschrieben. Standardmäßig aus.log_level— wie laut jede Entscheidung protokolliert wird:info,notice(Standardwert),warnodererror.
Furchtlos mit dry_run=on ausrollen. Es zeichnet jeden Bann auf, den es aussprechen würde, ohne den Zustand zu verändern, sodass Sie Schwellenwerte gegen Live-Datenverkehr kalibrieren können — sogar neben einem durchsetzenden Standort in derselben Zone — und dann live schalten.
Die Guten ausnehmen — abuse_guard_allow
Kontext: http · server · location · wiederholbar, nach unten vererbt.
abuse_guard_allow 127.0.0.0/8;
abuse_guard_allow 10.0.0.0/8 192.168.0.0/16;
Aufgeführte Clients werden nie gezählt und nie gesperrt. Der Abgleich erfolgt auf der tatsächlichen Verbindungsadresse, sodass es mit realip zusammenarbeitet. So schützen Sie auch verifizierte Such-Crawler: Erlauben Sie die veröffentlichten Googlebot-/Bingbot-Bereiche, damit ein Bot, der sich durch veraltete URLs arbeitet (und 404s anhäuft), nie erwischt wird.
Sperren über den Fleet teilen — abuse_guard_redis
Kontext: http
abuse_guard_redis host=10.0.0.5 password=… ; # tls://host für TLS
abuse_guard_zone zone=clients:10m redis=on;
Richten Sie jeden Knoten auf eine Redis- oder Valkey-Instanz aus, schalten Sie redis=on um, und ein auf einer Maschine verdienter Bann verbreitet sich auf alle. Standardwerte: port=6379, db=0, prefix=ag_, timeout=100ms. Wie es schnell bleibt, wird im nächsten Abschnitt erklärt.
SELinux: Auf Systemen mit erzwungenem SELinux (RHEL, Rocky, AlmaLinux) blockiert der Kernel NGINX daran, die Verbindung zu Redis zu öffnen, bis Sie es einmal erlauben — setsebool -P httpd_can_network_connect 1. Überspringen Sie dies, und die Replikation tut stillschweigend nichts, während die lokale Durchsetzung normal weiterläuft.
Eine Sperre, jeder Knoten — ohne einen einzigen Request zu verlangsamen
Hinter einem Load-Balancer ist eine Pro-Server-Sperre Theater: Der Angreifer landet einfach auf einem anderen Knoten. Abuse Guard schließt diese Lücke, ohne Redis jemals in den Request-Pfad zu legen.
Jeder Knoten entscheidet lokal und zählt lokal. In dem Moment, in dem er eine Sperre ausgibt, sendet er diese eine Tatsache an den Cluster und zeichnet eine dauerhafte Kopie auf. Jeder andere Knoten importiert sie innerhalb von Millisekunden, und jeder Knoten, der offline war, gleicht sich in dem Moment ab, in dem er sich wieder verbindet. Da die Durchsetzung immer aus dem eigenen In-Memory-Zustand jedes Knotens bedient wird, wartet die Anfrage eines Besuchers nie auf eine Netzwerk-Round-Trip — die einzigen Kosten der Clusterung bestehen darin, dass ein frisch gebannter Angreifer einen Herzschlag später statt sofort fleetweit ausgesperrt wird.
Redis ist hier eine Einbahn-Alarmglocke, kein gemeinsames Hauptbuch, das pro Anfrage konsultiert wird — ein langsames oder fehlendes Redis kann Ihrem Datenverkehr also niemals Latenz hinzufügen. Betreiben Sie es in einem privaten Netzwerk und behandeln Sie es als privilegiert: Alles, was hineinschreiben kann, kann Sperren ausgeben.
Sperren, die einen Neustart überleben
Zeigen Sie mit einer Zone auf eine Datei, und aktive Sperren werden beim sauberen Worker-Exit gespeichert und beim Start wiederhergestellt. Reloads und geordnete Neustarts behalten aktuelle Sperren, ohne einen periodischen Ganzzonen-Schreiber auszuführen. Ein abruptes Prozess- oder Maschinenversagen kann seit dem letzten sauberen Exit ausgegebene Sperren verlieren; die Durchsetzung schlägt weiterhin offen fehl.
abuse_guard_zone zone=clients:10m
persist=/var/lib/nginx/abuse_guard/clients.state
persist_secret=00112233445566778899aabbccddeeff;
Der kompakte Snapshot enthält nur Identitäts-Digests und Sperrfristen. CRC32 erkennt Beschädigungen, und eine atomare Umbenennung hält partielle Schreibvorgänge aus dem Live-Pfad heraus. Builds mit Unterstützung für signierte Snapshots können es zusätzlich mit persist_secret authentifizieren. Halten Sie das Verzeichnis nur für den Worker-Benutzer lesbar.
Alles sehen, was es entscheidet
Drei Variablen legen das Urteil von Abuse Guard für Ihre Protokolle und Konfiguration offen:
| Variable | Wert |
|---|---|
$abuse_guard_status |
BYPASSED · PASSED · COUNTED · BLOCKED · DRY_RUN |
$abuse_guard_count |
Aktueller gewichteter Score, auf einen ganzen Punkt gerundet. |
$abuse_guard_blocked_until |
Unix-Zeit, zu der die Sperre aufgehoben wird, oder 0. |
log_format guard '$remote_addr "$request" $status '
'guard=$abuse_guard_status count=$abuse_guard_count';
Schlüsselung hinter einem CDN oder Proxy? Vertrauen Sie niemals einem rohen X-Forwarded-For. Lassen Sie realip zuerst den echten Client auflösen und schlüsseln Sie dann auf $binary_remote_addr:
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Benötigen Sie eine Pro-Request-Ausnahmelogik? Jede Anfrage, deren key zu einer leeren Zeichenfolge aufgelöst wird, wird ignoriert — eine map ermöglicht es Ihnen also beispielsweise, anonyme Besucher per IP zu verfolgen, während authentifizierte Benutzer unberührt bleiben.
Entwickelt, um in der Produktion vertrauenswürdig zu sein
Abuse Guard wird an einem Standard gemessen, der weit über „es kompiliert" hinausgeht. Jede Änderung durchläuft das Spießrutenlaufen von AddressSanitizer, UndefinedBehaviorSanitizer, Valgrind, statischer Analyse und kontinuierlichem Fuzzing seiner Parser und des On-Disk-Formats. Seine optionalen Abhängigkeiten — Clusterung und signierte Snapshots — sind bewusst Best-Effort: Wenn Redis oder die Festplatte sich fehlverhalten, führt die Durchsetzung ruhig aus dem lokalen Speicher fort. Ihr Datenverkehr wird nie von einer Abhängigkeit als Geisel gehalten.
Abuse Guard erhalten
Abuse Guard ist ein kommerzielles NGINX-Modul von GetPageSpeed LLC, geliefert mit fortlaufenden Updates und Support durch ein GetPageSpeed-Abonnement.
- Durchsuchen Sie den vollständigen NGINX-Modul-Katalog → https://nginx-extras.getpagespeed.com/modules/
- Lizenzierung, Volumenbereitstellungen oder Hilfe beim Einrichten → getpagespeed.com/contact-us
© GetPageSpeed LLC. Alle Rechte vorbehalten.