Πλημμύρα scraper στο δωρεάν πρόγραμμα της Cloudflare: τι τη σταμάτησε και τι αφήσαμε απενεργοποιημένο
Λειτουργίες
Μια πρωινή, μια σελίδα προϊόντων του δικού μας site σταμάτησε να ανοίγει. Η Cloudflare εμφανίζει στους επισκέπτες σφάλμα 524, ο origin εξυπηρετητής χρειαζόταν δύο έως έξι λεπτά ανά σελίδα και τίποτα δεν μας ειδοποίησε για περίπου δέκα ώρες. Η αιτία ήταν ένας scraper που περνούσε μέσω residential proxies με περίπου 225 αιτήματα το δευτερόλεπτο.
Η μορφή της πλημμύρας
- Χιλιάδες διευθύνσεις, ένα έως τρία αιτήματα η καθεμία. Συνδέσεις ευρυζωνικότητας σπιτιών στις ΗΠΑ, την Ισπανία, τη Γαλλία, τη Βραζιλία, το Ηνωμένο Βασίλειο και αλλού, ο τύπος κίνησης που νοικιάζει ένα δίκτυο residential proxy.
- User agents Chrome σε Mac, με αριθμούς έκδοσης από 103 έως 151.
- Σχεδόν ποτέ cookie ή Referer. Από 2.697 αιτήματα που δειγματοληπτήσαμε στον server, 4 περιείχαν cookie και 4 Referer.
- Δύο είδη πελατών. Περίπου οι μισοί δεν έστελναν headers
Sec-Fetch-*ούτε client hints: ένα script με αντιγραμμένο user agent string. Οι άλλοι μισοί έστελναν πλήρη headers browser: ένα headless browser.
Κάθε σελίδα αποδιδόταν για κάθε αίτημα, οπότε κάθε worker έθετε σε ουρά εκατοντάδες renders και χτυπούσε το όριο του CPU.
Γιατί τα όρια ανά διεύθυνση δεν μπορούσαν να βοηθήσουν
Ένας περιορισμός ρυθμού μετρά αιτήματα ανά διεύθυνση. Με ένα έως τρία αιτήματα από καθεμία από χιλιάδες διευθύνσεις, καμία μεμονωμένη διεύθυνση δεν πλησιάζει ποτέ ένα όριο. Ο αποκλεισμός χωρών θα αποκλείει τους επισκέπτες μας. Αυτό που ο scraper δεν μπορούσε να πλαστογραφήσει φθηνά ήταν να συμπεριφέρεται σαν browser που έχει ήδη επισκεφθεί το site.
Στο edge της Cloudflare: τρεις δωρεάν κανόνες
Το δωρεάν πρόγραμμα επιτρέπει πέντε custom rules WAF ανά zone. Χρησιμοποιήσαμε τρεις, όλες με managed challenge αντί για block, ώστε ένα άτομο που πιάνεται κατά λάθος να περνάει κάνοντας κλικ:
- Ψεύτικο browser: ένα GET του οποίου το user agent περιέχει
Chrome/και το οποίο δεν έχει headerSec-Fetch-Mode. Κάθε Chrome από το 2019 το στέλνει. - Σύννεφα scraper: ένα αίτημα σελίδας από τα δίκτυα των Alibaba, Tencent και Huawei Cloud, από όπου προερχόταν μεγάλο μέρος όσων προκληθήκαμε.
- Έκτακτη ανάγκη, απενεργοποιημένη από προεπιλογή: ένα GET χωρίς καθόλου cookie και χωρίς Referer. Ένα άτομο που έχει επισκεφθεί το site, ή που φτάνει μέσω συνδέσμου, περνάει ανεπηρέαστο· ένας scraper που δεν κρατάει cookies συναντά challenge σε κάθε αίτημα. Το ενεργοποιούμε μόνο κατά τη διάρκεια πλημμύρας, επειδή προκαλεί επίσης κάποιον που πληκτρολογεί τη διεύθυνση σε ένα νέο browser.
Και οι τρεις επιτρέπουν τη διέλευση των επαληθευμένων bots της Cloudflare, των user agents που αυτοπροσδιορίζονται ως robots, των δικών μας διευθύνσεων, των μονοπατιών API και webhook, καθώς και των αρχείων που δεν είναι σελίδες. Δύο ημέρες αργότερα η πλημμύρα συνεχιζόταν: σε μία ώρα ο κανόνας για τα ψεύτικα προγράμματα περιήγησης έθεσε σε πρόκληση περισσότερα από 10.000 αιτήματα. Τα 10.000 συμβάντα που επιστρέφει η Cloudflare ανά ερώτημα προέρχονταν από 9.627 διευθύνσεις, καμία από τις οποίες δεν ξεπερνούσε τις 4.
Στον προέλευση: μια πύλη στην εφαρμογή
Το headless μέρος διαθέτει πλήρεις επικεφαλίδες προγράμματος περιήγησης, οπότε οι κανόνες στο άκρο του δικτύου δεν το εντοπίζουν από μόνοι τους όσο ο κανόνας έκτακτης ανάγκης είναι απενεργοποιημένος. Στην ίδια την εφαρμογή τοποθετήσαμε ένα μικρό middleware μπροστά από τον αποδοτικό σελίδας:
- ένα user agent Chrome χωρίς
Sec-Fetch-Modeούτε client hints λαμβάνει 403 πριν γίνει οποιαδήποτε εργασία· - ένας ξένος, χωρίς κανένα από τα cookies μας και χωρίς Referer, εξυπηρετείται μόνο όταν ο worker διαθέτει ελεύθερη χωρητικότητα, σε λίγες σελίδες ανά δευτερόλεπτο. Πάνω από αυτό, μια σελίδα 503 μεγέθους 400 byte ορίζει ένα cookie και επαναφορτώνει μετά από δύο δευτερόλεπτα. Ένα άτομο λαμβάνει τη σελίδα στην δεύτερη προσπάθεια· ένας scraper που δεν κρατά cookies δεν τη λαμβάνει ποτέ.
Το πρώτο λεπτό η πύλη απέρριψε περίπου 6.700 ψεύτικα προγράμματα περιήγησης και απώθησε περίπου 6.700 ξένους, εξυπηρετώντας τους ξένους σε περίπου 9 σελίδες ανά δευτερόλεπτο. Τα αργά αιτήματα έπεσαν στο μηδέν, ο CPU των workers έπεσε από το όριό τους στο 12 με 15 τοις εκατό, και η μνήμη τους από 4 με 5 GB το καθένα στα 0,65 GB.
Τι αφήσαμε απενεργοποιημένο
- Bot Fight Mode. Θέτει σε πρόκληση την αυτοματοποιημένη κίνηση και δεν μπορεί να παρακαμφθεί με προσαρμοσμένο κανόνα στο πλάνο Free, ενώ εντόπισε τα webhooks του παρόχου πληρωμών μας.
- Λειτουργία Under Attack για ολόκληρη τη ζώνη. Βάζει κάθε επισκέπτη, API client και webhook μέσω της ενδιάμεσης σελίδας. Ο κανόνας έκτακτης ανάγκης κάνει την ίδια δουλειά μόνο για τα αιτήματα σελίδων από ξένους.
- Ο κανόνας περιορισμού ρυθμού του πλάνου Free. Μετρά ανά διεύθυνση, κάτι που αυτή η πλημμύρα δεν ενεργοποιεί ποτέ.
- Αποκλεισμός crawlers AI. Θέλουμε να μας βρίσκουν οι βοηθοί αναζήτησης AI, και αυτοί οι crawlers δεν ήταν το πρόβλημα.
Το συμπέρασμα
Μια πλημμύρα μέσω residential proxies είναι εύκολο να εντοπιστεί από όσα της λείπουν: browser fetch headers, cookies και Referers. Θέστε σε πρόκληση στο άκρο του δικτύου, κρατήστε τους ξένους εντός των ορίων που μπορούν να αποδώσουν οι workers σας, και βεβαιωθείτε ότι κάτι εκτός του διακομιστή αντιλαμβάνεται όταν μια σελίδα σταματήσει να ανοίγει. Η Νυχτερινή Φύλαξη συσκευάζει και τα τρία: τη φύλαξη, τους κανόνες με αυτόματη εναλλαγή για τον κανόνα έκτακτης ανάγκης, και την πύλη για web εφαρμογές Python.