- Eine Zusammenstellung von Methoden, um ohne CDN durch die Kombination von HTTP-Protokoll/IP-Bereichen/Client-Signalen/TCP-Eigenschaften/TLS-Fingerprints/Content-Komprimierung die meisten Bots mit mangelhafter Implementierung oder Konfiguration zu blockieren
- Alle Methoden müssen selektiv angepasst werden; ohne vorherige Analyse von 1–3 Jahren Access-Logs könnten VPN-Nutzer/Suchmaschinen/CDNs/Schulen/Bibliotheken/Nutzer bestimmter Sprachen mit blockiert werden
- Das Blockieren von HTTP/1.1-Clients und AS-/CIDR-Bereichen von Rechenzentren kann viele Bots entfernen, kann aber auch Suchmaschinen einschließlich GoogleBot sowie legitime Nutzer in Rechenzentren ausschließen
- Nginx-Headerprüfungen und nftables-Filter für TCP-Fenstergröße/MSS/TTL reduzieren einfache Crawler und Scanner, können aber in legitimen Umgebungen wie LTE/VPN/Windows False Positives erzeugen
- Langfristig werden JA4-TLS-Fingerprint-Erkennung und ausschließlich Brotli-Antworten als Alternativen vorgeschlagen; vollständiges Blockieren wird jedoch nicht garantiert, und vor dem Einsatz bei umsatzgenerierenden Diensten wird gewarnt
Blockierumfang und Voraussetzungen für den Einsatz
- Zuerst sollte entschieden werden, ob das Ziel einige Bots, die meisten Bots oder alle Bots sind
- Die hier behandelten Ansätze zielen nicht auf sämtliche ausgefeilte Automatisierungstools, sondern darauf, die meisten Bots mit mangelhafter Implementierung oder Konfiguration relativ einfach zu blockieren
- Für jede Methode wird auch das Risiko angegeben, legitime Nutzer und Suchmaschinen zu blockieren
- Nachdem der Beitrag am 26. Juli 2026 auf Hacker News geteilt wurde, sollen die meisten Blockierfunktionen vom Blog auf eine separate Demo-Site verlagert werden, sodass daraus ein Puzzle wird, bei dem Leser nach dem Lesen der Methode selbst Zugriffe versuchen
- Alle Einstellungen können selektiv angepasst oder weggelassen werden; vor einem realen Einsatz sind ausreichende Recherche und Tests nötig
- Da legitime Nutzer, interne Systeme einer Organisation oder abhängige externe Dienste blockiert werden können, liegt die Verantwortung für den Einsatz vollständig beim Betreiber
- Nicht in produktiven Umgebungen einsetzen, die Umsatz generieren
Methode 1: Unterscheidung nach HTTP-Protokoll
- Das Risiko, legitime Nutzer zu blockieren, ist niedrig; das Risiko, einige Suchmaschinen zu blockieren, ist mittel
- Genutzt wird der Unterschied, dass normale Browser HTTP/2.0 verwenden, viele Bots jedoch HTTP/1.1
- GoogleBot wird als Nutzer von HTTP/1.1 betrachtet und durch diese Methode blockiert
- Crawler von Bing und Facebook verwenden HTTP/2.0
- Dienste, die per HTTP/1.1 Linktitel oder kurze Vorschauen abrufen, können ebenfalls blockiert werden
- Opera Mini wird ebenfalls ausgeschlossen
- In Nginx wird konfiguriert, dass bei
$server_protocol ungleich HTTP/2.0 auf eine andere Seite umgeleitet oder 200, 403 beziehungsweise 444 zurückgegeben wird
if ($server_protocol != HTTP/2.0) {
return 403 'Upgrade your client';
}
- Bei Rückgabe von
444 kann die Verbindung ohne separate Antwort geschlossen werden
- Ob der Nutzen größer ist als der Verlust durch das Blockieren von Google-Suchtraffic, muss jede Organisation selbst beurteilen
Methode 2: IP-Bereiche von Rechenzentren blockieren
- Das Blockierrisiko für normale Heim- und LTE-Nutzer ist niedrig, für VPN-Nutzer mittel; Suchmaschinen, die in Rechenzentren laufen, haben ein hohes Blockierrisiko
- In den Access-Logs der letzten 1–2 Jahre werden folgende Signale kombiniert, um verdächtige Requests zu finden
- HTTP-Protokoll
- User-Agent
Accept-Language
Sec-Fetch-Mode
Accept
- Verdächtige IPs werden in BGP Tools oder im Hurricane Electric BGP Toolkit nachgeschlagen, um das zugehörige AS und die angekündigten Prefixe zu prüfen
- Die bereitgestellte Liste von Netzwerk-Blackholes kann auch CDN- und Suchmaschinen-Bereiche enthalten und muss daher selektiv angewendet werden
- Vor separaten Listen wird bereits eine Konfiguration genutzt, die die Bereiche
3/8, 10/8, 11/8, 25/8, 26/8, 38/8, 41/8, 60/8, 61/8, 200/8, 224/3 als Blackholes behandelt
- Nachdem die Prefix-Seite eines AS kopiert wurde, werden per Shell-Funktion nur die CIDRs extrahiert und anschließend sortiert, dedupliziert und zusammengeführt
- Verwendet wird sum_cidr.pl; dafür ist das Perl-Modul
Net::CIDR::Lite erforderlich
- Das erzeugte Ergebnis wird nach Prüfung in Dateien unter
/usr/local/etc/*.netset verschoben
- Beim Serverstart wird jede CIDR als Blackhole-Route hinzugefügt
for CflIP in $(grep -E ^[1-9] /usr/local/etc/_cloudflare.netset); do
/sbin/ip route add blackhole "${CflIP}" 2>/dev/null
done
- Im Beispiel wird der gesamte Cloudflare-Bereich blockiert, um keine Requests über Workers und Ähnliches anzunehmen
- Statt ipset-Regeln in der Firewall wird Routing gewählt, weil Linux-Blackhole-Routing weniger CPU verbraucht
- Auch der IP-Bereich des Hosting-Anbieters, in dem der aktuelle Server liegt, kann blockiert werden
- DNS, Konfiguration und interne Dienste dürfen denselben Adressraum nicht verwenden
- Direkt verbundene Gateway-Routen haben Vorrang vor Blackhole-Routen
Methode 3: Länder/Proxys/Tor/bösartige IPs blockieren
- Listen aus dem Repository FireHOL Blocklists werden heruntergeladen, und die benötigten Bereiche werden als Blackhole-Routen hinzugefügt
- Da die Listendateien Kommentare enthalten, müssen diese vor der Verarbeitung mit
grep -Ev '^#' entfernt werden
- Besonders empfohlen werden folgende Listen
firehol_abusers_30d.netset
firehol_level2.netset
- Große Listen können die Laufzeit des Startskripts verlängern
- Auch die Konfigurationsdateien, die für den realen Server und die Firewall-Konfiguration verwendet wurden, werden bereitgestellt
Methode 4: HTTP-Client-Signale prüfen
- User-Agent und Header können gefälscht werden, aber die Annahme ist, dass einfache Bots, die auf Geschwindigkeit optimiert sind, dies oft nicht korrekt tun
- Für Requests mit
Curl oder Wget wird Klartext zurückgegeben; für Requests mit Bot, GPT, LLM oder Spider wird 410 Gone zurückgegeben
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'; }
- Einige beobachtete User-Agent-Teilstrings werden mit einem langen regulären Ausdruck geprüft, um Crawler, Scanner und Sammeltools zu blockieren
- Enthalten sind Teilstrings wie
Go-http, Java, libwww, okhttp, urllib, python, nmap, zgrab, semrush, shodan, rss, scrap, crawler, headless, github, facebook, google, bing
- Vor dem Einsatz sollten 2–3 Jahre User-Agents aggregiert werden, um zu prüfen, ob echte legitime Clients auf den regulären Ausdruck passen
sort access-user-agents.txt | uniq -c | sort
- Wenn ein passender Request HTTP/1.1 nutzt, wird er mit hoher Wahrscheinlichkeit als Bot behandelt; GoogleBot ist jedoch als Ausnahme zu berücksichtigen
- Bei HTTP/2.0-Requests wird zusätzlich die IP-Zugehörigkeit mit BGP-Tools geprüft
Sec-Fetch-Mode
Sec-Fetch-Mode wird den Access-Logs hinzugefügt; wenn der Wert nicht cors, no-cors oder navigate ist, wird blockiert
if ($http_sec_fetch_mode !~ (cors|no-cors|navigate)) {
return 410 '1000101';
}
Referer-Prüfung
- Um Requests zu verhindern, die Inhalte von anderen Sites einbetten oder scannen, wird blockiert, wenn der
Referer bestimmte Zeichenketten enthält
- Geprüft werden Zeichenketten rund um Admin-Seiten, Suchmaschinen, soziale Netzwerke, Kryptowährungen, Erwachsenen-Inhalte, Scanner und WordPress
- Bestimmte Bot-Typen, die die Google-Root-Seite
https://www.google.com/ als Referer behaupten, werden ebenfalls separat blockiert
- Dieses Muster wurde bei Requests beobachtet, die sich als altes Android ausgeben
HTTP-Methoden einschränken
- Erlaubt werden nur die für normale Browser-Requests nötigen Methoden
GET und POST; andere Methoden werden blockiert
if ($request_method !~ (^GET$|^POST)) {
return 410 '1000101';
}
- In der realen Anwendung können Pfade, die
POST benötigen, genauer eingeschränkt werden; falls nicht benötigt, kann POST komplett ausgeschlossen werden
Prüfung auf Proxys und Browser-ähnliches Verhalten
- Ist der Header
X-Forwarded-For vorhanden, wird der Request als Proxy-Request betrachtet und blockiert
- Auch legitime Shared-Proxy-Umgebungen wie Schulen oder Bibliotheken können dadurch blockiert werden
- Wenn der User-Agent keines von
Linux, BSD, Macintosh, Windows, Mozilla oder WhatsApp enthält, wird der Request als nicht browserähnlich betrachtet
- Es wird auch eine Regel genutzt, die blockiert, wenn
Accept-Language weder en noch es enthält
- Die Wahrscheinlichkeit ist hoch, dass dadurch einige Browser und legitime Nutzer blockiert werden, die kein Englisch oder Spanisch verwenden
- Außerdem wird eine optionale Regel vorgestellt, die Spracheinstellungen mit
br oder sy separat blockiert
Scans sensibler Pfade blockieren
- Werden folgende Dateien oder Pfade angefordert, gilt dies als automatischer Scan und wird blockiert
Methode 5: TCP-Scanner mit nftables blockieren
- In der
PREROUTING-Chain der raw-Tabelle von nftables werden Eigenschaften von TCP-SYN-Paketen geprüft
- Die Beispiel-Serveradresse
172.238.221.88 wird explizit als Ziel angegeben, um False Positives zu reduzieren, die bei Paketverlust entstehen können
- Unter den auf Port 80/443 eingehenden SYN-Paketen werden folgende Bedingungen blockiert
- TCP-Fenstergröße unter 12.288 Byte
- MSS außerhalb des Bereichs 1.220–1.460
- Als Kriterium wird genutzt, dass echte Clients größere Fenstergrößen verwenden und MSS-Werte außerhalb dieses Bereichs mit geringer Wahrscheinlichkeit zu legitimen Clients gehören
- Eine exakte Beschränkung der MSS auf
1460 wäre strenger, kann aber die meisten LTE- und VPN-Nutzer blockieren
Optionale Einschränkung nach TTL
- Wenn die TTL eines TCP-SYN größer als
128 ist, lassen sich die meisten LTE-Geräte blockieren
- Wenn die TTL größer als
64 ist, werden auch die meisten Windows-Systeme blockiert
- Die Standard-TTL-Werte werden wie folgt beschrieben
- Linux/Mac/BSD:
64
- Windows:
128
- LTE: noch größer
Connection Tracking ausschließen
- Ports 80/443 werden als
notrack markiert, sodass Web-Traffic nicht in die conntrack-Tabelle gelangt
- In diesem Fall müssen auch in der filter-Tabelle zustandslose Regeln für Ein- und Ausgangsrichtung direkt konfiguriert werden
- Im Beispiel wird Traffic zwischen Client-Quellports
1000-65535 und den Server-Ports 80/443 erlaubt
Methode 6: Erwachsenen-Inhalte und Robots-Header
- Für Zugangsbeschränkungen bei Erwachsenen-Inhalten wird der Header RTA: Restricted To Adults verwendet
- Altersverifikationsmethoden außer RTA werden als Mechanismen für Nutzer-Tracking und Monetarisierung betrachtet
- In Nginx-Antworten werden folgende Header immer hinzugefügt
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;
- Gewöhnliche Bots können diese Header ignorieren, sie können aber Suchmaschinen oder Bots beeinflussen, die darauf ausgelegt sind, Erwachsenen-Inhalte zu meiden
Methode 7: TLS-Fingerprint-Erkennung
- Die vorherigen Methoden 1–6 sind allesamt grobe Heuristiken; langfristig kann TLS-Fingerprint-Analyse die bessere Wahl sein
- JA4 kann genutzt werden, sofern Bots ihren TLS-Fingerprint nicht so ändern, dass er normalen Browsern entspricht
- Zunächst wird empfohlen, die Deployment-Methode in Deploying JA4 zu prüfen und anschließend FoxIO JA4 einzusetzen
Methode 8: Nur Brotli-komprimierte Inhalte ausliefern
- Site-Inhalte werden vorab mit Brotli komprimiert, und der Webserver wird so konfiguriert, dass er nur die komprimierten Dateien zurückgibt
- Dabei wird ausgenutzt, dass viele Bots Brotli-komprimiertes HTML nicht interpretieren können
- Nach der Anwendung wurde festgestellt, dass mehrere Bots Seitenlinks nicht mehr folgten und HTML offenbar nicht tatsächlich parsen konnten
- In Nginx wird konfiguriert, statische Brotli-Dateien immer auszuliefern
brotli_static always;
- HTML-Dateien werden wie folgt vorab komprimiert
cat ./i.html | brotli --best -fncv > ./i.html.br
Methode 9: Scanner zur Selbstidentifikation verleiten
- Eine separate Methode, um unerfahrene Angreifer und Scanner zu reduzieren, die wiederholt nach Schwachstellenpfaden suchen, wird in Help Attackers Self Report behandelt
1 Kommentare
Meinungen auf Hacker News
Aus der Perspektive von jemandem, der mehrere öffentliche Websites betreibt und andere Websites scrapt, um sie in Tools zu nutzen, frage ich mich, warum Bots die Leute so sehr beschäftigen.
Selbst ein WordPress mit Cache verarbeitet auf dem billigsten VPS etwa 1.000 Anfragen pro Sekunde, und eine ordentlich gebaute statische Website dürfte das Zehnfache schaffen. Ich frage mich, ob Blogs mit etwas wie Lambda ausgeliefert werden, oder ob es Zwanghaftigkeit ist, Abwehr von Schwachstellen oder eine Gewohnheit aus Zeiten, in denen Crawling echte Dienste beeinträchtigt hat.
Die Repositories sind Open Source und deshalb absichtlich öffentlich. Derzeit wehre ich mich mit einer einfachen Cookie-Prüfung, durch die nur wenige Bots kommen, aber das ist ein Kompromiss, bei dem ich Sichtbarkeit in Suchmaschinen opfern muss.
Es soll zeigen, wie man das auf Foren, Imageboards, Chatserver usw. anwenden kann; alle Optionen lassen sich anpassen oder abschalten. Vor dem echten Einsatz sollte man es auf einem Testserver prüfen, und es ist auch völlig in Ordnung, einfach darüber zu lachen und weiterzugehen.
Dass ich ein paar Sekunden länger brauche, um meinen lokalen IMAP-Server zu prüfen, weil die DMZ blockiert ist, ist kein Weltuntergang; trotzdem gibt es keinen Grund, das gutzufinden oder dauerhaft zuzulassen.
Am Wochenende habe ich die Weboberflächen viewvc (CVS/Subversion) und hgweb (Mercurial), die ich 10 bis 20 Jahre lang betrieben hatte, abgeschaltet. Von Residential-Proxy-IPs kamen 2,7 Millionen Anfragen pro Tag, im Schnitt 30 pro Sekunde, was alte uWSGI/CGI-Programme und andere Websites auf demselben Server belastete; außerdem näherte sich der Traffic dem VPS-Limit von 1 TB pro Monat.
Da es Millionen dynamischer VCS-URL-Kombinationen geben kann, ist auch der Cache-Effekt ungewiss, und es lohnte sich nicht, noch mehr Zeit in Server-Tuning zu stecken. Am Ende habe ich mich also für einen Schritt näher in Richtung zentralisiertes Internet entschieden.
Wenn man alles außer „zugelassenen“ User-Agents blockiert, hilft man dem bestehenden Browser-Monopol und beschleunigt die Dystopie. Genau vor solchen Problemen warnt RMS seit Jahrzehnten.
Wenn es ein Problem gibt, sollte man anhand von Traffic-Menge und Anfragefrequenz blockieren. Auch ich kann die Seite nicht aufrufen, werde mein Verhalten aber nicht daran anpassen; wie bei DRM kommen entschlossene Gegenparteien am Ende ohnehin durch.
Unabhängig von der Behauptung, man könne jeden Browser verwenden, sollte man jedoch besonders vorsichtig sein bei Browsern, die spontan generierter Code sind oder nicht ausreichend gegen bösartige Websites geprüft wurden. Auch Reader-Apps können gegenüber bösartigen Servern anfällig sein, wenn sie nicht von Penetrationstest-Experten einer umfassenden Drittcode-Prüfung unterzogen wurden.
Mir gefällt die Idee, eine gefälschte cpanel-Subdomain hinzuzufügen, die auf
169.254.169.254zeigt: Anfänger-Angreifer bringen damit ihren eigenen Hoster dazu, Portscans auszuführen, und können so erkannt oder blockiert werden.Die Quell-IPs waren über die ganze Welt verteilt, aber der eigentliche Scan-Lärm kam letztlich von einer einzigen Person.
IP-basiertes Blockieren sollte mit Vorsicht erfolgen. IP-Bereiche werden gelegentlich neu zugewiesen, sodass man die falschen Leute aussperren kann; ich habe auch mehrfach gesehen, dass Bereiche, die man wegen einer Region oder eines Rechenzentrums blockiert hatte, später an private ISPs übergingen.
Auch das Blockieren von HTTP/1.1 birgt ein hohes Risiko, echte Nutzer mit alten Browsern auszusperren. Außerdem gibt es Browser, die bei Cross-Origin-Requests nicht die vollständige URL senden; kommt der Traffic über die Google-Suche, kann der Referrer daher nur auf die Google-Startseite zeigen. Wer das vorschnell als Lüge eines Bots wertet und blockiert, kann sich auch den Traffic aus der Google-Suche abschneiden.
Dagegen halte ich das Blockieren von HTTP/1.1 für vertretbar. Seit mehr als zehn Jahren unterstützen fast alle Browser Protokolle darüber hinaus, und ein so alter Browser dürfte ohnehin auf weiten Teilen des Mainstream-Webs kaputtgehen; dass dann noch eine private Website nicht funktioniert, wäre keine Ausnahme, sondern Alltag.
Auch wenn dadurch alte Browser und API-Tools außen vor bleiben, werde ich das HTTP/1.1-Blocking beibehalten. Bei proprietärem Code in veralteten Finanzsystemen hätte ich Verständnis, aber das öffentliche Internet muss sich um seiner selbst willen aktualisieren.
Da ich Google schon seit Langem blockiere, sind alle Requests, die behaupten, von Google zu kommen, gelogen. Ich lasse mein Blog über mehrere zufällige Domains rotieren, um Zuordnungen und Snapshots zu durchbrechen, und versuche zu kontrollieren, über welche Wege Menschen meine Texte finden.
Nebenbei bekam ich auch einen kostenlosen Penetrationstest und kam zu dem Schluss, dass meine Abwehrmaßnahmen und die Verarbeitungspipeline robust sind. Durch den Überlebensdruck sind 90 % des Bot-Traffics zu VPNs abgewandert, sodass VPN-Endpunkte wie Weihnachtsbäume aufleuchten.
Ich könnte auch einen Feed mit Einmal-Zugriffs-IPs anbieten, aber Nutzer müssten ordentlich verifiziert und ihr Einsatzzweck genehmigt werden. Dieser Prozess macht an sich schon Spaß.
Wenn es nicht lesbar ist, kann man es im Archiv unter https://archive.ph/d3236 ansehen.
Ich bin kein Bot, möchte aber nicht iCloud Private Relay abschalten, nur um etwas zu lesen. Nach anderen Antworten des Autors ist es als Testseite eine gute Implementierung, aber andere Webadmins sollten möglichst nicht alle Methoden unverändert übernehmen.
Da im Antworttext nur 410 und der String
Sec-Fetch-Mode:auftauchen, scheint man mich für einen Bot gehalten zu haben. Es gibt nichts zu lesen oder zu sehen, also geht man einfach wieder; das moderne Web ist furchtbar.Den Support-Stand sieht man unter https://caniuse.com/?search=sec-fetch-mode, einige Header unter https://nochan.net/.env.
PR_END_OF_FILE_ERROR, also kam ich nicht einmal durch den TLS-Handshake.Ich vermute, dass über 99 % des Web-Traffics Bots oder Agents sind, und überlege, die Anzeige der Besucherzahlen zu entfernen. Die Zahlen sind bedeutungslos und lassen die Seite viel stärker frequentiert erscheinen, als sie ist; ich zögere aber mit Gegenmaßnahmen, weil ich befürchte, dass echte Menschen dann meine Texte nicht lesen oder Bücher nicht herunterladen können.
Wenn Blockieren nötig ist, ist eine Allowlist in der Regel wirksamer als eine Denylist; wenn man keine Allowlist einsetzen kann, ist auch diese Methode möglicherweise keine gute Lösung.
Tools wie Cloudflare und Anubis können erhebliche Barrierefreiheitsprobleme verursachen, daher bevorzuge ich Rate-Limiting. Es ist sauber, ohne die Zugänglichkeit zu beeinträchtigen, und bei vorübergehenden Problemen funktionieren auch kurze IP-Sperren gut.
Persönlich analysiere ich mit fail2ban HTTP-Logs und blockiere IPs für N Stunden, wenn sie URLs anfordern, die in
robots.txtverboten sind, Pfade wiewp-login.phpaufrufen oder zu häufig das Rate-Limit überschreiten. In der Git-Web-UI teste ich derzeit Anubis.Schon mit fail2ban allein lässt sich ziemlich viel abwehren, allerdings muss man die ersten Monate die Regeln sorgfältig an die eigene Umgebung anpassen.
Zunächst habe ich mit dem Filter
failregex = ^ - \S+ \[\] ".*?" 40[034]erkannt und die Treffer dann in spezifischere Listen übernommen; inzwischen blockiere ich den gesamten Traffic mit rund 80 regulären Ausdrücken, sodass seit Langem keine Requests mehr bis zum allgemeinen40[034]-Filter durchkommen.Hinter einem Load Balancer oder Proxy braucht man allerdings eine Möglichkeit, die echte IP zu bekommen, was sowohl fail2ban als auch die Methode aus dem Original umständlich macht.
Nach diesen Kommentaren und meinem eigenen Zugriffsversuch sieht es so aus, als würde nicht nur Bot-, sondern auch der gesamte legitime Traffic blockiert.
Sonntags sieht man am häufigsten die ungewöhnlichen Browser und Apps, mit denen Menschen im Web unterwegs sind; an Wochentagen gibt es mehr normale Mainstream-Browser, was einen guten Test ergibt.