Cloudflare Ücretsiz planında bir scraper akını: Neyi durdurduk, neyi kapalı bıraktık
Operasyonlar
Bir sabah ürün tanıtım sayfalarımızdan biri açılmayı bıraktı. Cloudflare ziyaretçilere 524 hatası gösteriyordu, kaynak sunucu sayfa başına iki ila altı dakika alıyordu ve yaklaşık on saat boyunca bize hiçbir şey bildirilmedi. Neden, konut tipi proxy'ler üzerinden saniyede yaklaşık 225 istek yapan bir scraper'dı.
Akının şekli
- Binlerce adres, her birinden bir ila üç istek. ABD, İspanya, Fransa, Brezilya, İngiltere ve başka yerlerdeki ev geniş bant bağlantıları; konut proxy ağlarının kiraladığı türden trafik.
- Mac üzerinde Chrome kullanıcı ajanları, 103 ile 151 arası sürüm numaralarıyla.
- Neredeyse hiç çerez veya Referer yok. Sunucuda örneklediğimiz 2.697 istekten 4'ü çerez, 4'ü Referer taşıyordu.
- İki tür istemci. Yaklaşık yarısı
Sec-Fetch-*başlıklarını ve istemci ipuçlarını göndermiyordu: Kopyalanmış bir kullanıcı ajanı dizesi olan bir betik. Diğer yarısı tam tarayıcı başlıkları gönderiyordu: Başsız (headless) bir tarayıcı.
Her istek için her sayfa oluşturulduğundan, her worker yüzlerce render işini kuyruğa atıyor ve CPU sınırına takılıyordu.
Adres başına limitler neden işe yaramadı
Bir hız limiti, adres başına istekleri sayar. Binlerce adresten her birinden bir ila üç istek geldiğinde, hiçbir tek adres bir limite yaklaşmaz. Ülkeleri engellemek ziyaretçilerimizi de engellerdi. Scraper'ın ucuza taklit edemediği şey, daha önce siteye gelmiş bir tarayıcı gibi davranmaktı.
Cloudflare kenarında: üç ücretsiz kural
Ücretsiz plan, bölge başına beş WAF özel kuralına izin verir. Üçünü kullandık, hepsi engelleme yerine yönetilen bir meydan okuma (challenge) içeriyordu, böylece yanlışlıkla takılan bir kişi tıklayarak geçebilir:
- Sahte tarayıcı: Kullanıcı ajanı
Chrome/içeren veSec-Fetch-Modebaşlığı olmayan bir GET isteği. 2019'dan bu yana her Chrome bunu gönderir. - Scraper bulutları: Alibaba, Tencent ve Huawei Cloud ağlarından gelen sayfa istekleri; meydan okuduğumuz isteklerin çoğu buralardan geliyordu.
- Acil durum, varsayılan olarak kapalı: Hiç çerez ve Referer içermeyen bir GET isteği. Siteye daha önce gelmiş veya bir bağlantı üzerinden gelen kişi dokunulmadan geçer; çerez tutmayan bir scraper her istekte bir meydan okumayla karşılaşır. Bunu yalnızca akın sırasında açarız, çünkü taze bir tarayıcıya adresi yazan birini de meydan okumaya tabi tutar.
Üçü de Cloudflare'ın doğrulanmış botlarına, kendilerini robot olarak tanımlayan kullanıcı ajanlarına, kendi adreslerimize, API ve webhook yollarına ve sayfa olmayan dosyalara izin verir. İki gün sonra sel devam ediyordu: Bir saat içinde sahte tarayıcı kuralı 10.000'den fazla isteğe meydan okudu. Cloudflare'ın sorgu başına döndürdüğü 10.000 olay, 9.627 adresten geliyordu ve hiçbiri 4'ü geçmiyordu.
Kaynakta: Uygulamada bir kapı
Başsız (headless) kısım tam tarayıcı başlıklarına sahip olduğundan, acil durum kuralı kapalıyken uç kurallar tek başına onu yakalamaz. Uygulamanın kendisinde sayfa oluşturucunun önüne küçük bir ara yazılım (middleware) koyduk:
Sec-Fetch-Modeveya istemci ipuçları (client hints) içermeyen bir Chrome kullanıcı ajanı, herhangi bir işlem yapılmadan önce 403 alır;- Bizim çerezlerimizden hiçbiri ve Referer başlığı olmayan bir yabancı, yalnızca işçi (worker) boş kapasiteye sahipken saniyede birkaç sayfa hızında hizmet alır. Bu eşiğin üzerinde, 400 baytlık bir 503 sayfası bir çerez ayarlar ve iki saniye sonra yeniden yükler. Bir kişi sayfayı ikinci denemede alır; çerez tutmayan bir kazıyıcı (scraper) asla alamaz.
Kapı ilk dakikasında yaklaşık 6.700 sahte tarayıcıyı reddetti ve yaklaşık 6.700 yabancıyı geri çevirdi; aynı zamanda yabancılara saniyede yaklaşık 9 sayfa sundu. Yavaş istekler sıfıra düştü, işçilerin CPU kullanımı sınırlarından yüzde 12-15'e, bellek kullanımları ise her biri için 4-5 GB'dan 0,65 GB'a indi.
Kapalı bıraktıklarımız
- Bot Fight Mode. Otomatik trafiğe meydan okur ve Ücretsiz planda özel bir kuralla atlanamaz; ödeme sağlayıcımızın webhook'larını da yakaladı.
- Tüm bölge için Under Attack modu. Her ziyaretçiyi, API istemcisini ve webhook'u geçiş sayfasından (interstitial) geçirir. Acil durum kuralı, aynı işi yalnızca yabancıların sayfa istekleri için yapar.
- Ücretsiz planın hız sınırlama kuralı. Adres başına sayar; bu sel onu hiç tetiklemez.
- AI tarama botlarını engelleme. AI arama asistanları tarafından bulunmak istiyoruz ve bu tarama botları sorun değildi.
Çıkarılacak ders
Konut tipi vekil sunucular (residential proxies) üzerinden gelen bir sel, eksik olan şeylerle kolayca fark edilir: tarayıcı fetch başlıkları, çerezler ve Referer başlıkları. Bunu uçta (edge) meydan okuma ile karşılayın, yabancileri işçilerinizin oluşturabileceği sınırlar içinde tutun ve bir sayfa açılmayı bıraktığında sunucunun dışındaki bir şeyin bunu fark ettiğinden emin olun. Night Watch üçünü de paketler: gözetim mekanizması, acil durum için otomatik anahtarlı kurallar ve Python web uygulamaları için kapı.