- Synthèse de méthodes pour bloquer la plupart des bots mal implémentés ou mal configurés, sans CDN, en combinant protocole HTTP/plages IP/signaux client/caractéristiques TCP/empreintes TLS/compression de contenu
- Toutes les méthodes doivent être ajustées au cas par cas ; sans analyse préalable de 1 à 3 ans de journaux d’accès, elles peuvent aussi bloquer des utilisateurs de VPN, moteurs de recherche, CDN, écoles, bibliothèques ou utilisateurs de certaines langues
- Bloquer les clients HTTP/1.1 et les plages AS/CIDR de datacenters permet d’éliminer beaucoup de bots, mais peut aussi exclure GoogleBot et d’autres moteurs de recherche, ainsi que des utilisateurs légitimes de datacenters
- Les contrôles d’en-têtes Nginx et les filtres nftables sur la taille de fenêtre TCP/MSS/TTL réduisent les crawlers et scanners simples, mais peuvent générer des faux positifs dans des environnements légitimes comme LTE/VPN/Windows
- À long terme, l’article propose la détection d’empreintes TLS JA4 et des réponses exclusivement en Brotli comme alternatives, sans garantir un blocage complet, et avertit de ne pas les utiliser pour un service générant des revenus
Périmètre du blocage et prérequis d’application
- Il faut d’abord décider si l’objectif est de bloquer certains bots, la plupart des bots ou tous les bots
- Les méthodes abordées ici ne visent pas tous les outils d’automatisation sophistiqués, mais cherchent surtout à bloquer assez simplement la plupart des bots mal implémentés ou mal configurés
- Pour chaque méthode, le risque de bloquer des utilisateurs légitimes et des moteurs de recherche est également indiqué
- Après le partage sur Hacker News le 26 juillet 2026, la plupart des fonctions de blocage du blog seront déplacées vers un site de démonstration séparé, transformé en puzzle où les lecteurs lisent la méthode puis tentent d’y accéder directement
- Tous les réglages peuvent être modifiés ou omis de manière sélective ; une enquête et des tests suffisants sont nécessaires avant toute mise en production
- Des utilisateurs légitimes, des systèmes internes à une organisation ou des services externes dont vous dépendez peuvent être bloqués ; la responsabilité de l’application incombe donc entièrement à l’opérateur
- À ne pas utiliser dans un environnement de production générant des revenus
Méthode 1 : distinguer par protocole HTTP
- Le risque de bloquer des utilisateurs légitimes est faible, et celui de bloquer certains moteurs de recherche est moyen
- La méthode exploite le fait que les navigateurs ordinaires utilisent HTTP/2.0, tandis que beaucoup de bots utilisent HTTP/1.1
- GoogleBot est considéré comme utilisant HTTP/1.1 et sera bloqué par cette méthode
- Les crawlers de Bing et Facebook utilisent HTTP/2.0
- Les services qui récupèrent un titre de lien ou un court aperçu en HTTP/1.1 peuvent aussi être bloqués
- Opera Mini est également exclu de la cible
- Dans Nginx, configurer
$server_protocol pour rediriger vers une autre page ou renvoyer 200, 403 ou 444 s’il n’est pas HTTP/2.0
if ($server_protocol != HTTP/2.0) {
return 403 'Upgrade your client';
}
- Renvoyer
444 permet de couper la connexion sans réponse distincte
- Chaque organisation doit juger elle-même si les bénéfices dépassent les pertes liées au blocage du trafic entrant depuis Google Search
Méthode 2 : bloquer les plages IP de datacenters
- Le risque de bloquer des utilisateurs résidentiels/LTE légitimes est faible, mais il est moyen pour les utilisateurs de VPN, et élevé pour les moteurs de recherche opérant depuis des datacenters
- Dans les journaux d’accès des 1 à 2 dernières années, combiner les signaux suivants pour repérer les requêtes suspectes
- Protocole HTTP
- User-Agent
Accept-Language
Sec-Fetch-Mode
Accept
- Rechercher les IP suspectes dans BGP Tools ou Hurricane Electric BGP Toolkit pour identifier leur AS et les préfixes annoncés
- La liste de blackholes réseau fournie peut aussi inclure des plages de CDN et de moteurs de recherche ; elle doit donc être appliquée de manière sélective
- La configuration utilisée blackhole déjà, avant toute liste séparée, les plages
3/8, 10/8, 11/8, 25/8, 26/8, 38/8, 41/8, 60/8, 61/8, 200/8, 224/3
- Après avoir copié la page des préfixes d’un AS, une fonction shell extrait uniquement les CIDR, puis les trie, déduplique et fusionne
- Elle utilise sum_cidr.pl et nécessite le module Perl
Net::CIDR::Lite
- Le résultat généré est examiné puis déplacé vers des fichiers
/usr/local/etc/*.netset
- Au démarrage du serveur, chaque CIDR est ajouté comme route blackhole
for CflIP in $(grep -E ^[1-9] /usr/local/etc/_cloudflare.netset); do
/sbin/ip route add blackhole "${CflIP}" 2>/dev/null
done
- Dans l’exemple, toute la plage Cloudflare est bloquée afin de ne pas recevoir de requêtes via Workers, entre autres
- Le choix du routage est motivé par le fait que le routage blackhole Linux consomme moins de CPU que les règles ipset du pare-feu
- Il est aussi possible de bloquer les plages de l’hébergeur auquel appartient le serveur actuel
- DNS, configuration et services internes ne doivent pas utiliser le même espace d’adressage
- Les routes de passerelle directement connectées sont appliquées avant les routes blackhole
Méthode 3 : bloquer pays/proxys/Tor/IP malveillantes
- Télécharger les listes du dépôt FireHOL Blocklists et ajouter les plages nécessaires comme routes blackhole
- Les fichiers de liste contenant des commentaires, il faut les supprimer avec
grep -Ev '^#' avant traitement
- Les listes suivantes sont particulièrement recommandées
firehol_abusers_30d.netset
firehol_level2.netset
- Les grandes listes peuvent allonger le temps d’exécution du script de démarrage
- Les fichiers de configuration utilisés pour le serveur réel et le pare-feu sont également fournis
Méthode 4 : inspecter les signaux du client HTTP
- Les User-Agent et en-têtes peuvent être falsifiés, mais l’hypothèse est que les bots simples, privilégiant la vitesse, ne les falsifient souvent pas correctement
- Renvoyer du texte brut aux requêtes
Curl et Wget, et 410 Gone aux requêtes contenant Bot, GPT, LLM ou Spider
if ($http_user_agent ~* Curl) { return 200 '\nGNU Terry Pratchett\n\n'; }
if ($http_user_agent ~* Wget) { return 200 '\nGNU Terry Pratchett\n\n'; }
if ($http_user_agent ~* Bot) { return 410 '1000101'; }
if ($http_user_agent ~* GPT) { return 410 '1000101'; }
if ($http_user_agent ~* LLM) { return 410 '1000101'; }
if ($http_user_agent ~* Spider) { return 410 '1000101'; }
- Tester certaines chaînes observées dans les User-Agent au moyen d’une longue expression régulière unique afin de bloquer crawlers, scanners et outils de collecte
- Elle inclut des sous-chaînes telles que
Go-http, Java, libwww, okhttp, urllib, python, nmap, zgrab, semrush, shodan, rss, scrap, crawler, headless, github, facebook, google, bing, etc.
- Avant application, agréger 2 à 3 ans de User-Agent pour vérifier si des clients réellement légitimes correspondent à l’expression régulière
sort access-user-agents.txt | uniq -c | sort
- Si la requête correspondante est en HTTP/1.1, la traiter comme probablement émise par un bot, tout en envisageant une exception pour GoogleBot
- S’il s’agit d’une requête HTTP/2.0, vérifier en plus l’appartenance de l’IP avec des outils BGP
Sec-Fetch-Mode
- Ajouter
Sec-Fetch-Mode aux journaux d’accès et bloquer si sa valeur n’est pas l’une de cors, no-cors, navigate
if ($http_sec_fetch_mode !~ (cors|no-cors|navigate)) {
return 410 '1000101';
}
Contrôle du Referer
- Bloquer lorsque
Referer contient certaines chaînes, afin d’empêcher les requêtes qui intègrent ou scannent le contenu depuis d’autres sites
- Cela vérifie notamment des chaînes liées aux pages d’administration, moteurs de recherche, réseaux sociaux, cryptomonnaies, contenu adulte, scanners et WordPress
- Bloquer séparément certains types de bots qui prétendent avoir comme Referer la page racine de Google
https://www.google.com/
- Il s’agit d’un motif observé dans des requêtes se faisant passer pour de vieux appareils Android
Restriction des méthodes HTTP
- N’autoriser que
GET et POST, nécessaires aux requêtes de navigateur normales, et bloquer les autres méthodes
if ($request_method !~ (^GET$|^POST)) {
return 410 '1000101';
}
- Dans l’application réelle, les chemins nécessitant
POST peuvent être restreints plus finement, ou totalement exclus si POST n’est pas utilisé
Contrôle des proxys et de l’apparence navigateur
- Si l’en-tête
X-Forwarded-For est présent, considérer la requête comme issue d’un proxy et la bloquer
- Des environnements légitimes de proxy partagé, comme des écoles ou bibliothèques, peuvent aussi être bloqués
- Si le User-Agent ne contient aucun de
Linux, BSD, Macintosh, Windows, Mozilla, WhatsApp, considérer que la requête ne ressemble pas à celle d’un navigateur
- Une règle bloquant lorsque
Accept-Language ne contient pas en ou es est également utilisée
- Elle risque fortement de bloquer certains navigateurs et des utilisateurs légitimes qui n’utilisent pas l’anglais ou l’espagnol
- Une règle optionnelle distincte bloquant les paramètres de langue contenant
br ou sy est aussi proposée
Bloquer les scans de chemins sensibles
- Demander les fichiers ou chemins suivants est considéré comme un scan automatisé et entraîne un blocage
Méthode 5 : bloquer les scanners TCP avec nftables
- Inspecter les caractéristiques des paquets TCP SYN dans la chaîne
PREROUTING de la table raw de nftables
- Préciser l’adresse d’exemple du serveur
172.238.221.88 comme destination afin de réduire les faux positifs pouvant survenir en cas de perte de paquets
- Parmi les paquets SYN entrants sur les ports 80/443, bloquer les conditions suivantes
- Taille de fenêtre TCP inférieure à 12 288 octets
- MSS hors de la plage 1 220–1 460
- Le critère utilisé est que les clients réels utilisent une taille de fenêtre plus grande, et qu’un MSS hors de cette plage a peu de chances de correspondre à un client légitime
- Restreindre exactement le MSS à
1460 est plus strict, mais peut bloquer la plupart des utilisateurs LTE et VPN
Restriction optionnelle basée sur le TTL
- Si le TTL du TCP SYN est supérieur à
128, cela permet de bloquer la plupart des appareils LTE
- S’il est supérieur à
64, la plupart des systèmes Windows sont également bloqués
- Les TTL par défaut sont décrits ainsi
- Linux/Mac/BSD :
64
- Windows :
128
- LTE : valeur supérieure
Exclusion du suivi de connexion
- Définir les ports 80/443 en
notrack pour ne pas placer le trafic web dans la table conntrack
- Dans ce cas, il faut aussi configurer directement, dans la table filter, des règles sans état pour les deux sens de trafic
- Dans l’exemple, le trafic est autorisé entre les ports source client
1000-65535 et les ports serveur 80/443
Méthode 6 : contenu adulte et en-têtes robots
- Pour la restriction d’accès au contenu adulte, utiliser l’en-tête RTA: Restricted To Adults
- Les méthodes de vérification d’âge autres que RTA sont considérées comme destinées au suivi utilisateur et à la monétisation
- Ajouter toujours les en-têtes suivants aux réponses Nginx
add_header Rating 'RTA-5042-1996-1400-1577-RTA' always;
add_header adult 'porn, sex, politics, religion, philosophy' always;
add_header X-Robots-Tag "none,noindex,nofollow,nosnippet,noai" always;
- Les bots ordinaires peuvent ignorer ces en-têtes, mais ils peuvent affecter les moteurs de recherche ou les bots conçus pour éviter le contenu adulte
Méthode 7 : détection d’empreintes TLS
- Les méthodes 1 à 6 ci-dessus sont toutes des heuristiques grossières ; à long terme, l’analyse d’empreintes TLS peut être une meilleure option
- JA4 peut être exploité à condition que les bots ne modifient pas leur empreinte TLS pour la rendre identique à celle d’un navigateur légitime
- Il est conseillé de consulter d’abord la méthode de déploiement dans Deploying JA4, puis d’appliquer FoxIO JA4
Méthode 8 : ne fournir que du contenu compressé en Brotli
- Précompresser le contenu du site en Brotli et configurer le serveur web pour ne renvoyer que les fichiers compressés
- La méthode exploite le fait que beaucoup de bots ne savent pas interpréter du HTML compressé en Brotli
- Après application, plusieurs bots ont cessé de suivre les liens de la page, confirmant qu’ils ne parvenaient pas réellement à analyser le HTML
- Dans Nginx, configurer la fourniture systématique des fichiers Brotli statiques
brotli_static always;
- Les fichiers HTML sont précompressés comme suit
cat ./i.html | brotli --best -fncv > ./i.html.br
Méthode 9 : pousser les scanners à s’identifier eux-mêmes
- Une méthode distincte pour réduire les scanners et attaquants débutants qui explorent de manière répétée des chemins de vulnérabilités est abordée dans Help Attackers Self Report
1 commentaires
Avis sur Hacker News
Comme j'exploite plusieurs sites web publics et que je récupère des contenus d'autres sites pour mes outils, je me demande pourquoi les gens se préoccupent autant des bots
Même un WordPress avec cache peut gérer environ 1 000 requêtes par seconde sur le VPS le moins cher, et un site statique bien conçu pourrait probablement en gérer 10 fois plus. Je me demande si ces blogs sont servis via quelque chose comme Lambda, ou s'il s'agit d'une obsession, d'une défense contre les vulnérabilités, ou d'une habitude héritée de l'époque où le crawling affectait réellement le service
Les dépôts sont open source, donc je les laisse publics exprès. Pour l'instant, je me défends avec une simple vérification de cookie et seuls quelques bots passent, mais c'est un compromis qui sacrifie la visibilité dans les moteurs de recherche
L'idée est de montrer comment l'appliquer à des forums, imageboards, serveurs de chat, etc., et toutes les options peuvent être ajustées ou désactivées. Il faut valider ça sur un serveur de test avant de l'utiliser en production, et vous pouvez aussi simplement en rire et passer à autre chose
Que mon serveur IMAP local mette quelques secondes de plus à répondre parce que la DMZ est saturée, ce n'est pas dramatique, mais ce n'est pas une raison pour aimer ça ou continuer à le tolérer
Ce week-end, j'ai fermé les interfaces web viewvc (CVS·Subversion) et hgweb (Mercurial) que j'exploitais depuis 10 à 20 ans. Elles recevaient 2,7 millions de requêtes par jour depuis des IP de proxy résidentielles, soit 30 requêtes par seconde en moyenne, ce qui pesait sur d'anciens programmes uWSGI/CGI et sur d'autres sites hébergés sur le même serveur, et le trafic approchait aussi la limite mensuelle de 1 To de mon VPS
Comme les combinaisons dynamiques d'URL VCS peuvent se compter en millions, l'efficacité du cache était incertaine, et cela ne valait pas le temps supplémentaire à passer à régler le serveur, j'ai fini par faire un choix qui nous rapproche encore un peu plus d'un Internet centralisé
Si l'on bloque tout sauf les user agents « approuvés », on renforce le monopole des navigateurs existants et on accélère la dystopie. C'est précisément le genre de problème contre lequel RMS alerte depuis des décennies
Si c'est vraiment un problème, il faut bloquer en fonction du volume de trafic et de la fréquence des requêtes. Moi non plus je ne peux pas accéder à ce site, mais je ne compte pas adapter mon comportement pour autant, et comme avec les DRM, un adversaire déterminé finira de toute façon par passer
Cela dit, indépendamment de l'argument selon lequel on devrait pouvoir utiliser n'importe quel navigateur, il faut se méfier tout particulièrement des navigateurs générés à la volée ou insuffisamment audités face aux sites malveillants. Une appli de lecture aussi peut être vulnérable à des serveurs malveillants si elle n'a pas fait l'objet d'un vaste audit de code tiers par des experts en tests d'intrusion
J'aime bien l'idée d'ajouter un faux sous-domaine cpanel pointant vers
169.254.169.254, ce qui peut pousser des attaquants novices à faire scanner en ports leur propre hébergeur et ainsi se faire détecter ou bloquerLes IP source étaient réparties partout dans le monde, mais en réalité tout ce bruit de scan venait d'une seule personne
Le blocage par IP demande de la prudence. Les plages d’IP sont parfois réattribuées, ce qui peut bloquer les mauvaises personnes, et j’ai vu plusieurs fois des plages bloquées parce qu’elles étaient associées à une région ou à un datacenter passer ensuite chez un FAI résidentiel
Bloquer HTTP/1.1 risque aussi de bloquer de vrais utilisateurs avec de vieux navigateurs. De plus, certains navigateurs n’envoient pas l’URL complète dans les requêtes cross-origin, donc si le trafic vient de la recherche Google, le referer peut ne pointer que vers la page racine de Google ; si on considère cela comme un mensonge de bot et qu’on le bloque, on peut aussi faire disparaître tout le trafic venant de Google Search
En revanche, le blocage de HTTP/1.1 me semble raisonnable. Cela fait plus de 10 ans que presque tous les navigateurs prennent en charge des protocoles plus récents, et un navigateur aussi ancien casse déjà sur la majeure partie du web actuel, donc qu’un site personnel de plus ne fonctionne pas ne serait pas une exception mais la norme
Même si cela fait rater de vieux navigateurs et des outils d’API, je compte maintenir le blocage de HTTP/1.1. Je comprends pour du code propriétaire dans de vieux systèmes financiers, mais l’Internet public doit se mettre à jour pour son propre bien
Comme je bloque Google depuis longtemps, toutes les requêtes prétendant venir de Google sont forcément mensongères. Je fais tourner mon blog sur plusieurs domaines aléatoires pour casser les liens de corrélation et les snapshots, et j’essaie de contrôler les chemins par lesquels les gens découvrent mes textes
J’ai aussi eu droit à un test d’intrusion gratuit, ce qui m’a permis de conclure que mes défenses et mon pipeline de traitement étaient solides. Sous la pression de la survie, 90 % du trafic de bots s’est déplacé vers des VPN, si bien que les points de terminaison VPN brillent comme des sapins de Noël
Je pourrais fournir un flux d’IP à accès unique, mais les utilisateurs devraient être correctement vérifiés et leur usage approuvé. Ce processus lui-même est amusant
Si vous ne pouvez pas le lire, il existe une archive : https://archive.ph/d3236
Je n’ai pas envie de désactiver iCloud Private Relay pour lire quelque chose alors que je ne suis même pas un bot. D’après une autre réponse de l’auteur, c’est une bonne implémentation comme site de test, mais j’aimerais que les autres admins web n’adoptent pas tous ces mécanismes tels quels si possible
Vu que le corps de la réponse ne contient que 410 et la chaîne
Sec-Fetch-Mode:, on dirait qu’il m’a pris pour un bot. Il n’y a rien à lire ni à voir, donc on repart simplement, et le web moderne est horribleOn peut vérifier la prise en charge sur https://caniuse.com/?search=sec-fetch-mode, et certains en-têtes sur https://nochan.net/.env
PR_END_OF_FILE_ERROR, ce qui signifie que même le handshake TLS n’est pas passéComme on peut s’attendre à ce que plus de 99 % du trafic web soit constitué de bots ou d’agents, j’envisage de supprimer l’affichage du nombre de visiteurs. Le chiffre n’a pas de sens et donne l’impression que le site est bien plus fréquenté qu’en réalité, mais j’hésite à réagir de peur d’empêcher de vraies personnes de lire les textes ou de télécharger les livres
Si un blocage est nécessaire, une allowlist est en général plus efficace qu’une denylist, et si l’on ne peut pas appliquer d’allowlist, cette méthode n’est peut-être pas non plus une bonne solution
Des outils comme Cloudflare et Anubis peuvent provoquer de graves problèmes d’accessibilité, donc je préfère la limitation de fréquence des requêtes. C’est propre, cela préserve l’accessibilité, et pour les problèmes temporaires un blocage d’IP de courte durée fonctionne aussi très bien
Personnellement, j’analyse les logs HTTP avec fail2ban pour bloquer pendant N heures les IP qui demandent des URL interdites dans
robots.txt, des chemins commewp-login.php, ou qui dépassent beaucoup trop souvent la limite de fréquence des requêtes. En ce moment, je teste Anubis sur l’interface web GitRien qu’avec fail2ban, on peut déjà bloquer assez efficacement, mais les premiers mois demandent un réglage fin adapté à l’environnement
J’ai d’abord détecté avec le filtre
failregex = ^ - \\S+ \\[\\] ".*?" 40[034], puis ajouté des règles plus spécifiques, et j’en suis maintenant à environ 80 expressions régulières, au point qu’aucune requête n’atteint plus depuis longtemps le filtre générique40[034]En revanche, derrière un load balancer ou un proxy, il faut un moyen d’obtenir la vraie IP, ce qui rend aussi bien fail2ban que la méthode du texte original plus pénibles
À voir ces commentaires et ma tentative d’accès, on dirait que non seulement les bots mais aussi tout le trafic légitime est bloqué
Le dimanche est le jour où l’on voit le plus de navigateurs et d’apps atypiques utilisés pour explorer le web, tandis qu’en semaine il y a davantage de navigateurs grand public ordinaires, ce qui en fait un bon test