Ein Scraper-Ansturm auf Cloudflares Free-Plan: Was ihn gestoppt hat und was wir ausgeschaltet ließen
Ops
Eines Morgens ließ sich eine unserer Listing-Seiten nicht mehr öffnen. Cloudflare zeigte Besuchern eine 524, der Origin brauchte zwei bis sechs Minuten pro Seite, und nichts meldete sich bei uns für etwa zehn Stunden. Die Ursache war ein Scraper, der über Residential-Proxies mit etwa 225 Anfragen pro Sekunde durch die Seiten ging.
Die Form des Ansturms
- Tausende Adressen, ein bis drei Anfragen pro Adresse. Heimische Breitbandanschlüsse in den USA, Spanien, Frankreich, Brasilien, dem Vereinigten Königreich und anderswo, die Art von Traffic, die ein Residential-Proxy-Netzwerk vermietet.
- Chrome-User-Agents auf einem Mac, mit Versionsnummern von 103 bis 151.
- Fast nie ein Cookie oder ein Referer. Von 2.697 Anfragen, die wir am Server stichprobenartig untersuchten, trugen 4 ein Cookie und 4 einen Referer.
- Zwei Arten von Clients. Etwa die Hälfte sandte keine
Sec-Fetch-*-Header und keine Client-Hints: ein Skript mit kopiertem User-Agent-String. Die andere Hälfte sandte vollständige Browser-Header: ein Headless-Browser.
Jede Seite wurde für jede Anfrage gerendert, sodass jeder Worker Hunderte von Renderings in die Warteschlange stellte und an seine CPU-Grenze stieß.
Warum Adress-Limits nicht halfen
Ein Rate-Limit zählt Anfragen pro Adresse. Bei ein bis drei Anfragen von jeder der Tausenden Adressen kommt keine einzelne Adresse auch nur in die Nähe eines Limits. Länder zu blockieren hätte unsere Besucher blockiert. Was der Scraper nicht günstig fälschen konnte, war, sich wie ein Browser zu verhalten, der die Seite schon einmal besucht hat.
Am Cloudflare-Edge: drei kostenlose Regeln
Der Free-Plan erlaubt fünf WAF-Custom-Regeln pro Zone. Wir nutzten drei, alle mit einer Managed Challenge statt einer Blockade, sodass eine Person, die versehentlich erfasst wird, durchklicken kann:
- Gefälschter Browser: ein GET, dessen User-Agent
Chrome/enthält und der keinenSec-Fetch-Mode-Header hat. Jedes Chrome seit 2019 sendet diesen. - Scraper-Clouds: eine Seitenanfrage aus den Netzwerken von Alibaba, Tencent und Huawei Cloud, von wo aus ein Großteil dessen kam, was wir herausforderten.
- Notfall, standardmäßig aus: ein GET ohne jegliches Cookie und ohne Referer. Eine Person, die die Seite schon besucht hat oder über einen Link kommt, bleibt unberührt; ein Scraper, der keine Cookies behält, trifft bei jeder Anfrage auf eine Challenge. Wir schalten sie nur während eines Ansturms ein, weil sie auch jemanden herausfordert, der die Adresse in einen frischen Browser eintippt.
Alle drei lassen Cloudflares verifizierte Bots, User-Agents, die sich als Roboter zu erkennen geben, unsere eigenen Adressen, die API- und Webhook-Pfade sowie Dateien, die keine Seiten sind, durch. Zwei Tage später lief die Flut noch immer: In einer Stunde stellte die Regel für Fake-Browser mehr als 10.000 Anfragen auf die Probe. Die 10.000 von Cloudflare pro Abfrage zurückgegebenen Ereignisse stammten von 9.627 Adressen, keine mit mehr als 4.
Am Origin: ein Gate in der App
Die headlose Hälfte hat vollständige Browser-Header, daher fangen die Edge-Regeln sie allein nicht ab, solange die Notfallregel deaktiviert ist. In der App selbst setzen wir ein kleines Middleware vor den Seiten-Renderer:
- ein Chrome-User-Agent ohne
Sec-Fetch-Modeund ohne Client-Hints erhält eine 403, bevor irgendeine Arbeit erledigt wird; - ein Fremder, ohne unsere Cookies und ohne Referer, wird nur bedient, solange der Worker Kapazität hat, mit wenigen Seiten pro Sekunde. Darüber hinaus setzt eine 400-Byte-503-Seite ein Cookie und lädt nach zwei Sekunden neu. Eine Person erhält die Seite beim zweiten Versuch; ein Scraper, der keine Cookies speichert, erhält sie nie.
In der ersten Minute lehnte das Gate etwa 6.700 Fake-Browser ab und wies etwa 6.700 Fremde ab, während es Fremden etwa 9 Seiten pro Sekunde auslieferte. Langsame Anfragen fielen auf null, die CPU der Worker sank von ihrem Limit auf 12 bis 15 Prozent und ihr Speicher von jeweils 4 bis 5 GB auf 0,65 GB.
Was wir deaktiviert ließen
- Bot Fight Mode. Er stellt automatisierten Traffic auf die Probe und kann im Free-Plan nicht mit einer benutzerdefinierten Regel umgangen werden; er hat die Webhooks unseres Zahlungsanbieters erwischt.
- Under Attack Mode für die gesamte Zone. Er schickt jeden Besucher, API-Client und Webhook durch die Zwischenseite. Die Notfallregel erledigt dieselbe Aufgabe nur für Seitenanfragen von Fremden.
- Die Rate-Limiting-Regel des Free-Plans. Sie zählt pro Adresse, was diese Flut nie auslöst.
- Blockieren von AI-Crawlern. Wir wollen von KI-Suchassistenten gefunden werden, und diese Crawler waren nicht das Problem.
Das Fazit
Eine Flut über Residential-Proxies ist leicht an dem zu erkennen, was ihr fehlt: Browser-Fetch-Header, Cookies und Referer. Fordern Sie das an der Edge heraus, halten Sie Fremde innerhalb dessen, was Ihre Worker rendern können, und stellen Sie sicher, dass etwas außerhalb des Servers bemerkt, wenn eine Seite nicht mehr öffnet. Night Watch bündelt alle drei: die Überwachung, die Regeln mit einem automatischen Schalter für die Notfallregel und das Gate für Python-Web-Apps.