Ett skrapertåg på Cloudflares kostnadsfria plan: vad som stoppade det och vad vi lämnade avstängt
Drift
En morgon slutade en av våra produktbeskrivningssidor att öppnas. Cloudflare visade besökare ett 524-fel, ursprungsservern tog två till sex minuter per sida, och inget varnade oss på ungefär tio timmar. Orsaken var en skrapare som gick via bostadsproxyer med cirka 225 förfrågningar i sekunden.
Tågets utformning
- Tusentals adresser, en till tre förfrågningar vardera. Bredbandsanslutningar i USA, Spanien, Frankrike, Brasilien, Storbritannien och andra länder, den typ av trafik som ett nätverk av bostadsproxyer hyr ut.
- Chrome-användaragenter på Mac, med versionsnummer från 103 till 151.
- Nästan aldrig en cookie eller ett Referer. Av 2 697 förfrågningar vi provade på servern hade 4 en cookie och 4 ett Referer.
- Två sorters klienter. Ungefär hälften skickade inga
Sec-Fetch-*-rubriker och inga klienttips: ett skript med en kopierad användaragentsträng. Den andra hälften skickade fullständiga webbläsarrubriker: en headless webbläsare.
Varje sida renderades för varje förfrågan, så varje arbetarprocess köade hundratals renderingar och nådde sin CPU-gräns.
Varför begränsningar per adress inte hjälpte
En hastighetsbegränsning räknar förfrågningar per adress. Med en till tre förfrågningar från vardera av tusentals adresser kommer ingen enskild adress i närheten av en gräns. Att blockera länder hade blockerat våra besökare. Det skraparen inte kunde fejka billigt var att bete sig som en webbläsare som har varit på sajten tidigare.
Vid Cloudflares edge: tre kostnadsfria regler
Den kostnadsfria planen tillåter fem anpassade WAF-regler per zon. Vi använde tre, alla med en hanterad utmaning istället för ett block, så att en person som fångas av misstag kan klicka sig igenom:
- Falsk webbläsare: en GET där användaragenten innehåller
Chrome/och som saknarSec-Fetch-Mode-rubrik. Varje Chrome sedan 2019 skickar den. - Skraparmolnar: en sidförfrågan från Alibaba-, Tencent- och Huawei Cloud-nätverken, där mycket av det vi utmanade kom ifrån.
- Nödläge, avstängt som standard: en GET utan cookie alls och utan Referer. En person som har varit på sajten, eller som kommer via en länk, passerar orörd; en skrapare som inte sparar cookies möter en utmaning vid varje förfrågan. Vi slår på den bara under ett tåg, eftersom den också utmanar någon som skriver adressen i en ny webbläsare.
Alla tre släpper igenom Cloudflares verifierade botar, användaragenter som namnger sig som robotar, våra egna adresser, API- och webhook-sökvägarna samt filer som inte är sidor. Två dagar senare pågick strömmen fortfarande: på en timme utmanade regeln för falska webbläsare fler än 10 000 förfrågningar. De 10 000 händelser Cloudflare returnerar per fråga kom från 9 627 adresser, ingen med fler än 4.
Vid ursprunget: en grind i appen
Den headless-halvan har fullständiga webbläsarheadrar, så kantreglarna fångar den inte ensam medan nödregeln är avstängd. I själva appen satte vi in en liten middleware framför sidrenderaren:
- en Chrome-användaragent utan
Sec-Fetch-Modeeller klienthintar får ett 403 innan något arbete utförs; - en främling, utan några av våra cookies och utan Referer, serveras bara när workern har ledig kapacitet, vid några sidor per sekund. Över det sätter en 400-byte 503-sida en cookie och laddar om efter två sekunder. En person får sidan på andra försöket; en scraper som inte behåller cookies får den aldrig.
Under den första minuten avvisade grinden cirka 6 700 falska webbläsare och vände bort cirka 6 700 främlingar, medan den serverade främlingar cirka 9 sidor per sekund. Långsamma förfrågningar föll till noll, workrarnas CPU sjönk från deras gräns till 12 till 15 procent, och deras minne från 4 till 5 GB vardera till 0,65 GB.
Vad vi lämnade avstängt
- Bot Fight Mode. Den utmanar automatiserad trafik och kan inte hoppas över med en anpassad regel på Free-planen, och den fångade vår betalningsleverantörs webhooks.
- Under Attack-läge för hela zonen. Den skickar varje besökare, API-klient och webhook genom interstitial-sidan. Nödregeln gör samma jobb bara för främlingars sidförfrågningar.
- Free-planens regel för hastighetsbegränsning. Den räknar per adress, vilket denna ström aldrig utlöser.
- Blockering av AI-crawlers. Vi vill hittas av AI-sökhjälpare, och de crawlers var inte problemet.
Slutsatsen
En ström genom bostadsproxyer är lätt att upptäcka på vad den saknar: webbläsarfetch-headrar, cookies och Referers. Utmana det vid kanten, håll främlingar inom vad dina workers kan rendera, och se till att något utanför servern märker när en slutar öppnas. Night Watch paketerar alla tre: bevakningen, reglerna med en automatisk omkopplare för nödregeln, och grinden för Python-webbappar.