การโจมตีแบบ flood จาก scraper บนแผน Free ของ Cloudflare: อะไรหยุดมันได้ และอะไรที่เราปล่อยทิ้งไว้

ปฏิบัติการ

เช้าวันหนึ่ง เว็บไซต์ listings ของเราเปิดไม่เข้า Cloudflare แสดง error 524 ให้ผู้เข้าชม ต้นทาง (origin) ใช้เวลาสองถึงห้านาทีต่อหน้า และไม่มีอะไรแจ้งเตือนเราเลยนานราวสิบชั่วโมง สาเหตุมาจาก scraper ที่วิ่งผ่าน residential proxies ด้วยความเร็วประมาณ 225 requests ต่อวินาที

ลักษณะของ flood

ทุกหน้าถูก render สำหรับทุก request ทำให้แต่ละ worker ต้องเข้าคิว render หลายร้อยครั้งจนชนเพดาน CPU

ทำไมการจำกัดจำนวนต่อ IP address จึงช่วยไม่ได้

Rate limit นับจำนวน requests ต่อ IP address เมื่อแต่ละ IP address จากหลายพันตัวส่งมาเพียงหนึ่งถึงสาม requests ไม่มี IP address ใดเข้าใกล้ขีดจำกัดเลย การบล็อกประเทศจะบล็อกผู้เข้าชมของเราไปด้วย สิ่งที่ scraper ทำได้ยากในราคาถูกคือ การทำตัวให้เหมือน browser ที่เคยเข้าเว็บมาก่อน

ที่ Cloudflare's edge: กฎฟรีสามข้อ

แผน Free อนุญาตให้ตั้ง WAF custom rules ได้ห้าข้อต่อ zone เราใช้สามข้อ โดยทั้งหมดตั้งค่าเป็น managed challenge แทนการบล็อก เพื่อให้คนที่ถูกจับผิดคลิกผ่านได้:

ทั้งสามอย่างเปิดทางให้บอทที่ยืนยันแล้วของ Cloudflare, user agent ที่ระบุตัวเองว่าเป็น robots, ที่อยู่ของเราเอง, เส้นทาง API และ webhook รวมถึงไฟล์ที่ไม่ใช่หน้าเว็บ สองวันต่อมา คลื่นข้อมูลยังคงไหลต่อเนื่อง: ในหนึ่งชั่วโมง กฎสำหรับเบราว์เซอร์ปลอมส่งคำขอไปตรวจสอบ (challenge) มากกว่า 10,000 ครั้ง เหตุการณ์ 10,000 รายการที่ Cloudflare ส่งกลับมาต่อการค้นหาหนึ่งครั้งมาจาก 9,627 ที่อยู่ โดยไม่มีที่อยู่ใดเกิน 4 ครั้ง

ที่ต้นทาง: ประตูในแอปพลิเคชัน

ฝั่ง headless มี headers ของเบราว์เซอร์ครบถ้วน ดังนั้นกฎที่ขอบ (edge) เพียงอย่างเดียวจึงจับมันไม่ได้ขณะปิดกฎฉุกเฉิน ในตัวแอปพลิเคชัน เราวาง middleware ขนาดเล็กไว้หน้าตัวเรนเดอร์หน้าเว็บ:

ในนาทีแรก ประตูปฏิเสธเบราว์เซอร์ปลอมประมาณ 6,700 ครั้ง และกันคนแปลกหน้าประมาณ 6,700 ครั้ง ขณะให้บริการคนแปลกหน้าประมาณ 9 หน้าต่อวินาที คำขอช้าลดลงเหลือศูนย์ CPU ของ worker ลดลงจากเพดานสูงสุดเหลือ 12 ถึง 15 เปอร์เซ็นต์ และหน่วยความจำลดลงจาก 4 ถึง 5 GB ต่อตัว เหลือ 0.65 GB

สิ่งที่เราปล่อยให้ปิดอยู่

บทสรุป

คลื่นข้อมูลผ่าน residential proxies ระบุได้ง่ายจากสิ่งที่ขาดหายไป: browser fetch headers, คุกกี้ และ Referers ให้ส่งคำขอเหล่านั้นไปตรวจสอบ (challenge) ที่ขอบ จำกัดคนแปลกหน้าให้อยู่ในขอบเขตที่ worker ของคุณเรนเดอร์ได้ และตรวจสอบให้แน่ใจว่ามีสิ่งนอกเซิร์ฟเวอร์ที่สังเกตได้เมื่อหน้าเว็บหยุดเปิด Night Watch รวมทั้งสามอย่างไว้ในชุดเครื่องมือเดียว: ตัวตรวจสอบระบบ, กฎพร้อมสวิตช์อัตโนมัติสำหรับกฎฉุกเฉิน และประตูสำหรับเว็บแอป Python

อัปเดตแล้ว: