Zum Inhalt

abuse-guard: Automatisches Sperren missbräuchlicher Clients durch Fehlerantwort-Rate

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-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 an den 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.0.0, veröffentlicht am 19. Juli 2026.


Ihr Fehlerprotokoll ist ein Geständnis. Abuse Guard liest es in Echtzeit und schließt Missbrauchstäter aus.

Jeder Scanner, Fuzzer und Credential-Stuffing-Bot hinterlässt denselben Fingerabdruck: eine Sprühflasche von 404s, die nach versteckten Pfaden suchen, 403s, die an verschlossenen Türen rütteln, fehlgeschlagene Anfragen nach fehlgeschlagenen Anfragen. Abuse Guard überwacht die Statuscodes, die Ihr Server tatsächlich zurückgibt, identifiziert die Clients, deren Verkehr größtenteils aus Fehlern besteht, und sperrt sie — entschieden innerhalb des NGINX-Workers, bei der Anfrage selbst, in wenigen Mikrosekunden. Kein Sidecar. Kein Log-Ship. Keine Skriptschicht. Nur kompilierter C-Code, der eine Aufgabe außergewöhnlich gut erledigt.

Spezifikationsblatt

Auslöser Pro-Client-Rate der Fehlerantworten, die Sie wählen (403/404 standardmäßig)
Aktion Zeitlich begrenzte Sperre — ein harter Bann für ein festes Zeitfenster, kein Drosseln
Entscheidungspunkt NGINX Preaccess-Phase, bevor irgendein Handler oder Upstream läuft
Speichermodell Feste Bytes pro Client, unabhängig von der Schwelle → botnet-skalierbar
Flottenmodus Optionale Bann-Replikation über Knoten hinweg via Redis / Valkey
Haltbarkeit Optionale Exit-Snapshots bewahren aktive Banns über Neustarts hinweg
Fußabdruck Ein eigenständiges Modul; standardmäßig keine 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. Missbrauchstäter erzeugen kaum etwas anderes — diese Asymmetrie ist das ganze Spiel. Ein Schwachstellenscanner, der Ihren Baum durchläuft, ist eine Wand aus 404s. Ein Bot, der Admin-Endpunkte ansticht, ist eine Wand aus 403s. Ein Brute-Force-Lauf ist eine Wand aus Fehlern.

Ratenbegrenzer behandeln diesen Verkehr wie jeden anderen: Sie verlangsamen alle nach Anfragevolumen und lassen den Täter sofort wieder rein, sobald es nachlässt. Abuse Guard macht das Gegenteil. Es ignoriert gutartigem Verkehr 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 die Last zu steuern. Verwenden Sie Abuse Guard, um Missbrauch auszuschließen.

Wie ein Bann entschieden wird

Drei bewegliche Teile, alle innerhalb des Workers:

1 · Ein undichter Score, pro Client. Jede Client-Identität trägt eine einzige kleine Zahl im gemeinsamen Speicher. Jeder übereinstimmende Fehler erhöht diesen Score; der Score sinkt kontinuierlich mit threshold ÷ interval pro Sekunde. Ein kurzer, scharfer Ausbruch bringt ihn über die Linie; ein langsames Tröpfeln tut dies nie. Entscheidend ist, dass dieser Score ein festes Datensatz ist, egal wie hoch Sie die Schwelle setzen — sodass eine einzige Zone bequem die Zehntausenden von verschiedenen Quelladressen verfolgt, die ein Botnetz auf Sie wirft.

2 · Eine harte Frist. In dem Moment, in dem der Score Ihre Schwelle überschreitet, erhält der Client einen blocked_until Zeitstempel. Bis dahin ist er einfach verschwunden — jede Anfrage wird in der Preaccess-Phase abgelehnt, bevor NGINX einen Zyklus mit Routing, Dateien oder Upstreams verbringt. Die Ablehnung ist das günstigste mögliche Ergebnis.

3 · Eine datenschutzkonforme Ablehnung. Gesperrte Clients erhalten 429 Too Many Requests (Ihr gewählter Code), so dass kein gemeinsamer Cache jemals speichern kann, dass eine Bestrafung eines Clients einem anderen zugewiesen wird, mit einem Retry-After, der ehrlichen Clients sagt, wann sie zurückkehren sollen.

Identitäten werden in einen festen Digest gefaltet, sodass das Keying auf etwas Großes wie $request_uri oder einen Header genau so viel Speicher kostet wie das Keying auf eine IP.

In weniger als einer Minute live

Abuse Guard wird als vorcompiliertes, signiertes Modul aus dem GetPageSpeed Repository geliefert — einfach einfügen, kein 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 gemeinsame Speicherzone

    server {
        location / {
            abuse_guard zone=clients;      # hier durchsetzen
        }
    }
}
sudo nginx -t && sudo systemctl reload nginx

Diese Standardwerte sperren jede IP, die innerhalb eines 5-Minuten-Fensters 100 403/404 Antworten zurückgibt, für eine Stunde. Straffen oder lockern Sie jede Zahl unten.

Konfiguration

Abuse Guard besteht aus vier Direktiven. Die erste erklärt eine Richtlinie; die anderen wenden sie an, befreien Personen davon und (optional) teilen sie über Maschinen hinweg.

Eine Richtlinie deklarieren — abuse_guard_zone

Eine http-Ebene Direktive. Sie schneidet eine gemeinsame Speicherzone aus und legt die Richtlinie fest, die sie regelt. Setzen Sie so viele oder so wenige Knöpfe, wie Sie möchten — der Name und die 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 als Fehler zählen
                  interval=300s                das Bewertungsfenster
                  threshold=100                Fehler in diesem Fenster  Bann
                  block=60m;                   wie lange der Bann hält

zone=clients:10m ist die Identität und das Budget der Richtlinie: ein Name, den Sie von abuse_guard referenzieren, und die Größe des gemeinsamen Speichers. Etwa 10 MB verfolgen etwa hunderttausend aktive Clients.

Alles andere ist optionale Feinabstimmung:

  • key — der Ausdruck, der einen einzelnen Client definiert. Jede NGINX-Variable; die Standardvariable $binary_remote_addr bezieht sich auf die Quell-IP. Eine Anfrage, deren Schlüssel leer ist, wird vollständig übersprungen (praktisch mit einer map, siehe unten).
  • statuses — die Antwortcodes, die als Fehler zählen: einzelne Codes, Bereiche oder eine Mischung, z.B. statuses=401,403,404,500-599. Standardmäßig 403,404.
  • interval — das Fenster, über das der Score abnimmt (Standard 300s). Ein Ausbruch innerhalb dieses Fensters löst einen Bann aus; ein langsames Tröpfeln, das sich weiter verbreitet, sammelt nie.
  • threshold — wie viele Fehler innerhalb dieses Fensters die Linie überschreiten, bis zu 1024 (Standard 100).
  • block — wie lange ein getrippter Client gesperrt bleibt (Standard 60m).
  • inactive — wie lange ein inaktiver Client im Speicher verweilt, bevor er zurückgefordert wird (Standard max(1h, interval, block); jeder explizite Wert muss mindestens so groß sein wie sowohl interval als auch block).
  • redison, um die Banns dieser Zone über eine Flotte zu replizieren (siehe unten); standardmäßig off.
  • persist — ein Dateipfad, wo aktive Banns beim sauberen Worker-Austritt gespeichert und beim Start geladen werden.
  • persist_secret — bei Builds mit Unterstützung für signierte Snapshots ein hexadezimaler Schlüssel, der HMAC-SHA256-Authentifizierung hinzufügt, sodass eine manipulierte Datei abgelehnt wird.

Warum 5xx standardmäßig ausgeschlossen ist: Ein Serverfehler ist normalerweise Ihr Fehler, und ihn zu zählen würde es einem fehlerhaften Backend ermöglichen, unschuldige Besucher zu sperren. Fügen Sie statuses=403,404,500-599 nur hinzu, wenn Sie absichtlich auf Clients reagieren möchten, die Serverfehler auslösen.

Anwenden — abuse_guard

Gültig in http, server und location Blöcken, sodass Sie eine gesamte Website oder nur die Endpunkte schützen können, die Missbrauch anziehen. Nennen Sie die Zone, um sie zu aktivieren; schreiben Sie abuse_guard off; in einem geschachtelten Bereich, um sie wieder auszuschalten.

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 gesperrter Client erhält, irgendwo in 400599 (Standard 429).
  • dry_runon, um zu beobachten, ohne durchzusetzen: das Urteil wird protokolliert, aber kein Bann wird geschrieben. Standardmäßig aus.
  • log_level — wie laut jede Entscheidung protokolliert wird: info, notice (Standard), warn oder error.

Rollout ohne Angst mit dry_run=on. Es protokolliert jeden Bann, den es ausgeben würde, ohne den Status zu berühren, sodass Sie die Schwellenwerte gegen den Live-Verkehr kalibrieren können — sogar neben einem durchsetzenden Standort in derselben Zone — und dann live umschalten.

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;

Aufgelistete Clients werden niemals gezählt und niemals gesperrt. Die Übereinstimmung erfolgt anhand der tatsächlichen Verbindungsadresse, sodass sie mit realip zusammenarbeitet. So schützen Sie auch verifizierte Suchcrawler: Erlauben Sie die veröffentlichten Googlebot / Bingbot-Bereiche, sodass ein Bot, der durch veraltete URLs gräbt (und 404s ansammelt), niemals erwischt wird.

Banns über die Flotte 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 einen Redis oder Valkey aus, aktivieren Sie redis=on, und ein Bann, der auf einer Maschine verdient wurde, wird auf alle propagiert. Standardwerte: port=6379, db=0, prefix=ag_, timeout=100ms. Wie es schnell bleibt, ist der nächste Abschnitt.

SELinux: Auf durchsetzenden Systemen (RHEL, Rocky, AlmaLinux) verhindert der Kernel, dass NGINX die Verbindung zu Redis öffnet, bis Sie es einmal erlauben — setsebool -P httpd_can_network_connect 1. Wenn Sie dies überspringen, funktioniert die Replikation stillschweigend nicht, während die lokale Durchsetzung normal weiterläuft.

Ein Bann, jeder Knoten — ohne eine einzige Anfrage zu verlangsamen

Hinter einem Lastenausgleich ist ein pro-Server-Bann Theater: Der Angreifer landet einfach auf einem anderen Knoten. Abuse Guard schließt diese Lücke ohne jemals Redis in den Anfragepfad zu setzen.

Jeder Knoten entscheidet lokal und zählt lokal. In dem Moment, in dem er einen Bann 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 aus, sobald er sich wieder verbindet. Da die Durchsetzung immer aus dem eigenen In-Memory-Zustand jedes Knotens erfolgt, wartet die Anfrage eines Besuchers niemals auf eine Netzwerk-Round-Trip — die einzige Kosten des Clustering ist, dass ein frisch gesperrter Angreifer flächendeckend einen Herzschlag später und nicht sofort ausgeschlossen wird.

Redis hier ist eine einseitige Alarmglocke, kein gemeinsames Hauptbuch, das pro Anfrage konsultiert wird — sodass ein langsames oder fehlendes Redis niemals Latenz zu Ihrem Verkehr hinzufügen kann. Führen Sie es in einem privaten Netzwerk aus und behandeln Sie es als privilegiert: Alles, was darauf schreiben kann, kann Banns ausgeben.

Banns, die einen Neustart überdauern

Richten Sie eine Zone auf eine Datei aus, und aktive Banns werden beim sauberen Austritt des Workers gespeichert und beim Start wiederhergestellt. Reloads und ordentliche Neustarts halten aktuelle Banns, ohne einen periodischen Voll-Zonen-Schreiber auszuführen. Ein abruptes Prozess- oder Maschinenversagen kann Banns verlieren, die seit dem letzten sauberen Austritt ausgegeben wurden; 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 Bann-Fristen. CRC32 erkennt Beschädigungen, und ein atomarer Umbenennungsprozess hält partielle Schreibvorgänge aus dem Live-Pfad fern. 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.

Sehen Sie alles, was es entscheidet

Drei Variablen geben das Urteil von Abuse Guard in Ihre Protokolle und Konfigurationen aus:

Variable Wert
$abuse_guard_status BYPASSED · PASSED · COUNTED · BLOCKED · DRY_RUN
$abuse_guard_count Fehler, die derzeit diesem Client zugeordnet sind.
$abuse_guard_blocked_until Unix-Zeit, zu der der Bann aufgehoben wird, oder 0.
log_format guard '$remote_addr "$request" $status '
                 'guard=$abuse_guard_status count=$abuse_guard_count';

Keying hinter einem CDN oder Proxy? Vertrauen Sie niemals auf ein rohes X-Forwarded-For. Lassen Sie realip zuerst den echten Client auflösen, und keyen 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;

Brauchen Sie eine Logik zur Ausnahmeregelung pro Anfrage? Jede Anfrage, deren key auf eine leere Zeichenfolge aufgelöst wird, wird ignoriert — sodass eine map es Ihnen ermöglicht, beispielsweise anonyme Besucher nach IP zu verfolgen, während authentifizierte Benutzer unberührt bleiben.

Entwickelt, um in der Produktion vertraut zu werden

Abuse Guard wird einem Standard weit über "es kompiliert" gehalten. Jede Änderung durchläuft die Prüfung von AddressSanitizer, UndefinedBehaviorSanitizer, Valgrind, statischer Analyse und kontinuierlichem Fuzzing seiner Parser und des On-Disk-Formats. Seine optionalen Abhängigkeiten — Clustering und signierte Snapshots — sind absichtlich als Best-Effort konzipiert: Wenn Redis oder die Festplatte fehlerhaft sind, setzt die Durchsetzung stillschweigend aus dem lokalen Speicher fort. Ihr Verkehr wird niemals als Geisel einer Abhängigkeit gehalten.

Holen Sie sich Abuse Guard

Abuse Guard ist ein kommerzielles NGINX-Modul von GetPageSpeed LLC, das mit laufenden Updates und Support über ein GetPageSpeed-Abonnement geliefert wird.

© GetPageSpeed LLC. Alle Rechte vorbehalten.