Un'inondazione di scraper sul piano gratuito di Cloudflare: cosa l'ha fermata e cosa abbiamo lasciato spento
Ops
Una mattina un nostro sito di schede prodotto ha smesso di aprirsi. Cloudflare mostrava ai visitatori un errore 524, l'origine impiegava da due a sei minuti per pagina e per circa dieci ore nessuno ci avvisava. La causa era uno scraper che passava attraverso proxy residenziali a circa 225 richieste al secondo.
La forma dell'inondazione
- Migliaia di indirizzi, da uno a tre richieste ciascuno. Connessioni a banda larga domestiche negli Stati Uniti, in Spagna, in Francia, in Brasile, nel Regno Unito e altrove, il tipo di traffico che una rete di proxy residenziali affitta.
- User agent Chrome su Mac, con numeri di versione da 103 a 151.
- Quasi mai un cookie o un Referer. Su 2.697 richieste campionate sul server, 4 portavano un cookie e 4 un Referer.
- Due tipi di client. Circa la metà non inviava header
Sec-Fetch-*né client hints: uno script con una stringa user agent copiata. L'altra metà inviava header browser completi: un browser headless.
Ogni pagina veniva renderizzata per ogni richiesta, quindi ogni worker accodava centinaia di render e raggiungeva il limite della CPU.
Perché i limiti per indirizzo non potevano aiutare
Un rate limit conta le richieste per indirizzo. Con una o tre richieste da ciascuno di migliaia di indirizzi, nessun singolo indirizzo si avvicina mai a un limite. Bloccare i paesi avrebbe bloccato i nostri visitatori. Ciò che lo scraper non poteva falsificare a basso costo era comportarsi come un browser che era già stato sul sito.
Al margine di Cloudflare: tre regole gratuite
Il piano gratuito consente cinque regole WAF personalizzate per zona. Ne abbiamo usate tre, tutte con una challenge gestita anziché un blocco, così una persona bloccata per errore può cliccare per procedere:
- Browser falso: una GET il cui user agent contiene
Chrome/e che non ha l'headerSec-Fetch-Mode. Ogni Chrome dal 2019 lo invia. - Cloud per scraper: una richiesta di pagina dalle reti di Alibaba, Tencent e Huawei Cloud, da dove proveniva gran parte di ciò che abbiamo sottoposto a challenge.
- Emergenza, spenta per impostazione predefinita: una GET senza alcun cookie e senza Referer. Una persona che è stata sul sito, o che arriva tramite un link, passa indenne; uno scraper che non conserva i cookie incontra una challenge a ogni richiesta. La attiviamo solo durante un'inondazione, perché sottopone a challenge anche chi digita l'indirizzo in un browser nuovo.
Tutti e tre lasciano passare i bot verificati di Cloudflare, gli user agent che si dichiarano robot, i nostri indirizzi, i percorsi API e webhook e i file che non sono pagine. Due giorni dopo il flusso era ancora in corso: in un'ora la regola per i falsi browser ha sottoposto a challenge oltre 10.000 richieste. I 10.000 eventi restituiti da Cloudflare per query provenivano da 9.627 indirizzi, nessuno con più di 4.
All'origine: un gate nell'app
La metà headless ha header di browser completi, quindi le sole regole edge non la intercettano mentre la regola d'emergenza è disattivata. Nell'app stessa abbiamo inserito un piccolo middleware davanti al renderer delle pagine:
- uno user agent Chrome senza
Sec-Fetch-Modené client hints riceve un 403 prima che venga eseguito qualsiasi lavoro; - uno sconosciuto, senza nessuno dei nostri cookie e senza Referer, viene servito solo se il worker ha capacità disponibile, a poche pagine al secondo. Oltre questa soglia, una pagina 503 da 400 byte imposta un cookie e ricarica dopo due secondi. Una persona ottiene la pagina al secondo tentativo; uno scraper che non conserva i cookie non la ottiene mai.
Nel primo minuto il gate ha rifiutato circa 6.700 falsi browser e respinto circa 6.700 sconosciuti, servendo agli sconosciuti circa 9 pagine al secondo. Le richieste lente sono scese a zero, la CPU dei worker è scesa dal loro limite al 12-15 percento e la loro memoria da 4-5 GB ciascuno a 0,65 GB.
Cosa abbiamo lasciato spento
- Bot Fight Mode. Sottopone a challenge il traffico automatizzato e non può essere saltato con una regola personalizzata sul piano Free, e ha intercettato i webhook del nostro provider di pagamenti.
- Under Attack mode per l'intera zona. Mette ogni visitatore, client API e webhook attraverso l'interstitial. La regola d'emergenza fa lo stesso lavoro solo per le richieste di pagina degli sconosciuti.
- La regola di rate limiting del piano Free. Conta per indirizzo, cosa che questo flusso non attiva mai.
- Bloccare i crawler AI. Vogliamo essere trovati dagli assistenti di ricerca AI, e quei crawler non erano il problema.
Il punto chiave
Un flusso attraverso proxy residenziali è facile da individuare per ciò che gli manca: header di fetch del browser, cookie e Referer. Sottoponilo a challenge al edge, tieni gli sconosciuti entro ciò che i tuoi worker possono renderizzare e assicurati che qualcosa fuori dal server si accorga quando una pagina smette di aprirsi. Night Watch include tutti e tre: la guardia, le regole con un interruttore automatico per quella d'emergenza e il gate per le web app Python.