שיטפון סקרייפר בתוכנית החינמית של Cloudflare: מה עצר אותו, ומה השארנו כבוי

תפעול

בוקר אחד, אחד מאתרי הדפים שלנו הפסיק להיפתח. Cloudflare הציבה למבקרים שגיאת 524, השרת המקור לקח בין שתיים לשש דקות לכל דף, ואף אחד לא עדכן אותנו במשך כ-10 שעות. הגורם היה סקרייפר שעבר דרך פרוקסים ביתיים בקצב של כ-225 בקשות לשנייה.

צורת השיטפון

כל דף עובד עבור כל בקשה, ולכן כל עובד (worker) תור מאות עיבודים והגיע למגבלת ה-CPU שלו.

למה מגבלות לפי כתובת לא יכלו לעזור

מגבלת קצב סופרת בקשות לפי כתובת. עם אחת עד שלוש בקשות מכל אחת מאלפי כתובות, אף כתובת בודדת לא מתקרבת למגבלה. חסימת מדינות הייתה חוסמת את המבקרים שלנו. מה שהסקרייפר לא יכל לזייף בזול היה להתנהג כמו דפדפן שכבר ביקר באתר.

בשולי Cloudflare: שלוש כללים חינמיים

התוכנית החינמית מאפשרת חמישה כללי WAF מותאמים אישית לכל אזור (zone). השתמשנו בשלושה, כולם עם אתגר מנוהל (managed challenge) במקום חסימה, כך שאדם שנתפס בטעות יכול להמשיך בלחיצה:

שלושתם מעבירים את הבוטים המאומתים של Cloudflare, סוכני משתמש שמצהירים על עצמם כרובוטים, הכתובות שלנו, נתיבי ה-API וה-webhook, וקבצים שאינם דפים. יומיים לאחר מכן השיטפון נמשך עדיין: בשעה אחת כלל הדפדפנים המזויפים ביצעו אתגר ליותר מ-10,000 בקשות. 10,000 האירועים שהחזירה Cloudflare לשאילתה הגיעו מ-9,627 כתובות, שאף אחת מהן לא עברה את 4.

במקור: שער באפליקציה

החצי חסר-הראש (headless) כולל כותרות דפדפן מלאות, ולכן כללי הקצה לבדם לא תופסים אותו בזמן שכלל החירום כבוי. באפליקציה עצמה שמנו תוכנת ביניים קטנה לפני מצייר הדף:

בדקה הראשונה השער דחה כ-6,700 דפדפנים מזויפים ודחה כ-6,700 זרים, תוך מתן שירות לזרים בכ-9 דפים בשנייה. בקשות איטיות ירדו לאפס, ה-CPU של העובדים ירד מהמגבלה שלהם ל-12 עד 15 אחוז, והזיכרון שלהם ירד מ-4 עד 5 גיגה-בייט לכל אחד ל-0.65 גיגה-בייט.

מה השארנו כבוי

המסקנה

שיטפון דרך פרוקסים ביתיים קל לזהות לפי מה שחסר בו: כותרות fetch של דפדפן, עוגיות ו-Referers. בצעו אתגר לכך בקצה, שמרו על זרים בתוך מה שהעובדים שלכם יכולים לרנדר, וודאו שמשהו מחוץ לשרת שם לב כאשר דף מפסיק להיפתח. Night Watch אורז את שלושתם: השמירה, הכללים עם מתג אוטומטי עבור כלל החירום, והשער עבור אפליקציות אינטרנט ב-Python.

עודכן: