abuse-guard: Auto-bannir les clients abusifs par taux de réponse d'erreur
Nécessite le plan Pro (ou supérieur) de l'abonnement GetPageSpeed NGINX Extras.
Installation
Vous pouvez installer ce module sur n'importe quelle distribution basée sur RHEL, y compris, mais sans s'y limiter :
- RedHat Enterprise Linux 7, 8, 9 et 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 et 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
Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :
load_module modules/ngx_http_abuse_guard_module.so;
Ce document décrit nginx-module-abuse-guard v2.0.0 publié le 19 juillet 2026.
Votre journal d'erreurs est une confession. Abuse Guard le lit en temps réel et exclut les abus.
Chaque scanner, fuzzer et bot de remplissage de credentials laisse la même empreinte :
une pluie de 404 à la recherche de chemins cachés, des 403 frappant des portes verrouillées, des requêtes échouées après des requêtes échouées. Abuse Guard surveille les codes d'état que votre serveur
retourne réellement, identifie les clients dont le trafic est principalement constitué d'échecs, et les exclut — décidé à l'intérieur du worker NGINX, sur la requête elle-même, en quelques microsecondes. Pas de sidecar. Pas de log shipper. Pas de couche de script. Juste du C compilé
faisant un travail exceptionnellement bien.
Fiche technique
| Déclencheur | Taux de réponses d'erreur par client que vous choisissez (403/404 par défaut) |
| Action | Verrouillage temporaire — un bannissement strict pour une fenêtre fixe, pas un ralentissement |
| Point de décision | Phase de préaccès NGINX, avant que tout gestionnaire ou upstream ne s'exécute |
| Modèle de mémoire | Octets fixes par client, indépendants du seuil → à l'échelle d'un botnet |
| Mode flotte | Réplication de bannissement optionnelle entre les nœuds via Redis / Valkey |
| Durabilité | Instantanés de sortie optionnels préservent les bans actifs entre les redémarrages |
| Empreinte | Un module autonome ; aucune dépendance d'exécution par défaut |
| Plateformes | RHEL / AlmaLinux / Rocky / CentOS Stream / Oracle / Amazon Linux |
| ## |
Le problème qu'il résout
Les visiteurs légitimes ne génèrent presque jamais une rafale d'erreurs. Les abus génèrent
peu d'autre chose — cette asymétrie est tout le jeu. Un scanner de vulnérabilités parcourant
votre arbre est un mur de 404. Un bot fouillant les points de terminaison administratifs est un mur de 403. Un essai de force brute est un mur d'échecs.
Les limiteurs de taux traitent ce trafic comme n'importe quel autre : ils ralentissent tout le monde par volume de requêtes et laissent l'infracteur revenir dès que cela se relâche. Abuse Guard fait le contraire. Il ignore complètement le trafic bien comporté et réserve sa seule réponse — un vrai bannissement limité dans le temps — pour les clients définis par leurs erreurs.
Utilisez un limiteur de taux pour façonner la charge. Utilisez Abuse Guard pour évincer les abus.
Comment un bannissement est décidé
Trois éléments en mouvement, tous à l'intérieur du worker :
1 · Un score fuyant, par client. Chaque identité de client porte un petit
nombre dans la mémoire partagée. Chaque erreur correspondante y ajoute ; le score s'épuise
continuement à threshold ÷ interval par seconde. Une courte rafale le pousse
au-delà de la limite ; un lent filet ne le fait jamais. De manière cruciale, ce score est un enregistrement de taille fixe
peu importe à quel point vous définissez le seuil — donc une seule zone suit confortablement
les dizaines de milliers d'adresses sources distinctes qu'un botnet vous lance.
2 · Une date limite stricte. Au moment où le score franchit votre seuil, le client
gagne un horodatage blocked_until. Jusqu'à ce moment, il est simplement parti — chaque requête
est rejetée à la phase de préaccès, avant que NGINX ne consacre un cycle au routage,
aux fichiers ou aux upstreams. Le rejet est le résultat le moins coûteux possible.
3 · Un refus correct en matière de confidentialité. Les clients bannis reçoivent 429 Too Many Requests
(votre choix de code) étiqueté de sorte qu'aucun cache partagé ne puisse jamais le stocker et servir la punition d'un client à un autre, avec un Retry-After indiquant aux clients honnêtes quand revenir.
Les identités sont intégrées dans un digest de taille fixe, donc se baser sur quelque chose de volumineux comme
$request_uri ou un en-tête coûte exactement autant de mémoire que de se baser sur une IP.
En direct en moins d'une minute
Abuse Guard est livré en tant que module précompilé et signé depuis le dépôt GetPageSpeed — déposez-le, aucun outil de construction requis.
sudo yum -y install https://extras.getpagespeed.com/release-latest.rpm
sudo yum -y install nginx-module-abuse-guard
Connectez-le :
load_module modules/ngx_http_abuse_guard_module.so;
http {
abuse_guard_zone zone=clients:10m; # une zone de mémoire partagée
server {
location / {
abuse_guard zone=clients; # appliquer ici
}
}
}
sudo nginx -t && sudo systemctl reload nginx
Ces valeurs par défaut bannissent toute IP qui retourne 100 403/404 réponses dans une
fenêtre de 5 minutes, pendant une heure. Resserrez ou assouplissez chaque nombre ci-dessous.
Configuration
Abuse Guard se compose de quatre directives. La première déclare une politique ; les autres l'appliquent, exemptent des personnes de celle-ci, et (optionnellement) la partagent entre les machines.
Déclarez une politique — abuse_guard_zone
Une directive de niveau http. Elle délimite une zone de mémoire partagée et définit la
politique qui la régit. Définissez autant ou aussi peu de paramètres que vous le souhaitez — le nom et la taille de la zone sont les seules choses que vous devez fournir ; des valeurs par défaut sensées remplissent le reste (les valeurs montrées ci-dessous sont exactement ces valeurs par défaut).
abuse_guard_zone zone=clients:10m ← nom + taille (le seul indispensable)
key=$binary_remote_addr ← qui est "un client"
statuses=403,404 ← quelles réponses comptent comme erreurs
interval=300s ← la fenêtre de notation
threshold=100 ← erreurs dans cette fenêtre → bannir
block=60m; ← combien de temps le bannissement dure
zone=clients:10m est l'identité et le budget de la politique : un nom que vous référencez
depuis abuse_guard, et la taille de la mémoire partagée. Environ 10 Mo suivent environ
une centaine de milliers de clients actifs.
Tout le reste est un réglage optionnel :
key— l'expression qui définit un seul client. N'importe quelle variable NGINX ; la valeur par défaut$binary_remote_addrse base sur l'IP source. Une requête dont la clé est vide est complètement ignorée (pratique avec unmap, ci-dessous).statuses— les codes de réponse qui comptent comme erreurs : codes individuels, plages, ou un mélange, par exemplestatuses=401,403,404,500-599. Par défaut403,404.interval— la fenêtre sur laquelle le score décroît (valeur par défaut300s). Une rafale à l'intérieur déclenche un bannissement ; un lent filet étalé ne s'accumule jamais.threshold— combien d'erreurs dans cette fenêtre franchissent la limite, jusqu'à 1024 (valeur par défaut100).block— combien de temps un client déclenché reste exclu (valeur par défaut60m).inactive— combien de temps un client dormant reste en mémoire avant d'être récupéré (valeur par défautmax(1h, interval, block); toute valeur explicite doit être au moins aussi grande queintervaletblock).redis—onpour répliquer les bans de cette zone entre une flotte (voir ci-dessous);offpar défaut.persist— un chemin de fichier où les bans actifs sont enregistrés lors de la sortie propre du worker et chargés au démarrage.persist_secret— sur les builds avec support de snapshot signé, une clé hexadécimale qui ajoute une authentification HMAC-SHA256 afin qu'un fichier altéré soit rejeté.
Pourquoi
5xxest laissé de côté par défaut : une erreur serveur est généralement le fait de votre côté, et le compter permettrait à un backend instable de faire bannir des visiteurs innocents. Ajoutezstatuses=403,404,500-599uniquement lorsque vous souhaitez délibérément agir sur les clients qui déclenchent des erreurs serveur.
Appliquez-la — abuse_guard
Valide dans les blocs http, server et location, donc vous pouvez protéger un site entier
ou juste les points de terminaison qui attirent les abus. Nommez la zone pour l'activer ; écrivez
abuse_guard off; dans un scope imbriqué pour la désactiver.
location /wp-login.php {
abuse_guard zone=clients status=429 log_level=warn;
}
zone— la zone (déclarée ci-dessus) dont la politique s'applique ici.status— le code qu'un client banni reçoit, n'importe où dans400–599(valeur par défaut429).dry_run—onpour observer sans appliquer : le verdict est enregistré mais aucun bannissement n'est écrit. Désactivé par défaut.log_level— à quel niveau chaque décision est enregistrée :info,notice(valeur par défaut),warn, ouerror.
Déployez sans crainte avec dry_run=on. Cela enregistre chaque bannissement qu'il ferait sans toucher à l'état, afin que vous puissiez calibrer les seuils par rapport au trafic en direct — même
à côté d'un emplacement d'application sur la même zone — puis le mettre en ligne.
Exemptez les bons gars — abuse_guard_allow
Contexte : http · server · location · répétable, hérité vers le bas.
abuse_guard_allow 127.0.0.0/8;
abuse_guard_allow 10.0.0.0/8 192.168.0.0/16;
Les clients listés ne sont jamais comptés et jamais bannis. La correspondance se fait sur la véritable
adresse de connexion, donc cela coopère avec realip. C'est aussi ainsi que vous protégez
les robots d'exploration de recherche vérifiés : autorisez les plages publiées de Googlebot / Bingbot pour qu'un
bot parcourant des URL obsolètes (et accumulant des 404) ne soit jamais pris.
Partagez les bans entre la flotte — abuse_guard_redis
Contexte : http
abuse_guard_redis host=10.0.0.5 password=… ; # tls://host pour TLS
abuse_guard_zone zone=clients:10m redis=on;
Pointez chaque nœud vers un Redis ou Valkey, activez redis=on, et un bannissement obtenu sur n'importe
quelle machine se propage à toutes. Valeurs par défaut : port=6379, db=0, prefix=ag_,
timeout=100ms. Comment cela reste rapide est la section suivante.
SELinux : sur les systèmes en mode d'application (RHEL, Rocky, AlmaLinux), le noyau empêche NGINX
d'ouvrir la connexion à Redis jusqu'à ce que vous le permettiez une fois —
setsebool -P httpd_can_network_connect 1. Ignorez cela et la réplication ne fait rien en silence
tandis que l'application locale continue normalement.
Un bannissement, chaque nœud — sans ralentir une seule requête
Derrière un équilibreur de charge, un bannissement par serveur est du théâtre : l'attaquant se retrouve simplement sur un autre nœud. Abuse Guard comble cette lacune sans jamais mettre Redis dans le chemin de la requête.
Chaque nœud décide localement et compte localement. L'instant où il émet un bannissement, il diffuse ce fait au cluster et enregistre une copie durable. Chaque autre nœud l'importe en quelques millisecondes, et tout nœud qui était hors ligne se réconcilie au moment où il se reconnecte. Parce que l'application est toujours servie à partir de l'état en mémoire de chaque nœud, la requête d'un visiteur n'attend jamais un aller-retour réseau — le seul coût du clustering est qu'un attaquant fraîchement banni est exclu à l'échelle de la flotte une battement plus tard au lieu d'instantanément.
Redis ici est une cloche d'alarme unidirectionnelle, pas un grand livre partagé consulté par requête — donc un Redis lent ou manquant ne peut jamais ajouter de latence à votre trafic. Exécutez-le sur un réseau privé et traitez-le comme privilégié : tout ce qui peut y écrire peut émettre des bans.
Bans qui survivent à un redémarrage
Pointez une zone vers un fichier et les bans actifs sont enregistrés lorsque le worker sort proprement, puis restaurés au démarrage. Les rechargements et redémarrages ordonnés conservent les bans actuels sans exécuter un écrivain de zone complet périodique. Une défaillance abrupte de processus ou de machine peut perdre les bans émis depuis la dernière sortie propre ; l'application échoue toujours en mode ouvert.
abuse_guard_zone zone=clients:10m
persist=/var/lib/nginx/abuse_guard/clients.state
persist_secret=00112233445566778899aabbccddeeff;
L'instantané compact contient uniquement des digests d'identité et des délais de bannissement. CRC32
détecte la corruption, et un renommage atomique garde les écritures partielles hors du chemin actif. Les builds avec support de snapshot signé peuvent en outre l'authentifier avec
persist_secret. Gardez le répertoire lisible uniquement par l'utilisateur worker.
Voir tout ce qu'il décide
Trois variables exposent le verdict d'Abuse Guard à vos journaux et à votre configuration :
| Variable | Valeur |
|---|---|
$abuse_guard_status |
BYPASSED · PASSED · COUNTED · BLOCKED · DRY_RUN |
$abuse_guard_count |
Erreurs actuellement attribuées à ce client. |
$abuse_guard_blocked_until |
Temps Unix à laquelle le bannissement prend fin, ou 0. |
log_format guard '$remote_addr "$request" $status '
'guard=$abuse_guard_status count=$abuse_guard_count';
Vous basez-vous derrière un CDN ou un proxy ? Ne faites jamais confiance à un X-Forwarded-For brut. Laissez
realip résoudre le véritable client d'abord, puis basez-vous sur $binary_remote_addr :
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Besoin d'une logique d'exemption par requête ? Toute requête dont la key se résout à une chaîne vide est ignorée — donc un map vous permet, par exemple, de suivre les visiteurs anonymes par IP tout en laissant les utilisateurs authentifiés intacts.
Conçu pour être fiable en production
Abuse Guard est soumis à une norme bien au-dessus de "cela compile." Chaque changement passe par le parcours d'AddressSanitizer, UndefinedBehaviorSanitizer, Valgrind, analyse statique, et fuzzing continu de ses parseurs et de son format sur disque. Ses dépendances optionnelles — clustering et snapshots signés — sont conçues pour être des efforts de bonne foi : si Redis ou le disque se comportent mal, l'application continue tranquillement à partir de la mémoire locale. Votre trafic n'est jamais pris en otage par une dépendance.
Obtenez Abuse Guard
Abuse Guard est un module NGINX commercial de GetPageSpeed LLC, livré avec des mises à jour et un support continus via un abonnement GetPageSpeed.
- Parcourez le catalogue complet des modules NGINX → https://nginx-extras.getpagespeed.com/modules/
- Licences, déploiements en volume, ou aide pour la configuration → getpagespeed.com/contact-us
© GetPageSpeed LLC. Tous droits réservés.