Loading...

امنیت · 8 دقیقه مطالعه

Rate limiting: جلوی سوءاستفاده را بگیرید بدون مسدودکردن مشتری‌ها

Rate limiting سقف تعداد درخواست‌هایی را تعیین می‌کند که یک کلاینت در یک بازهٔ زمانی می‌تواند بفرستد. ارزان‌ترین دفاعی است که در برابر brute-force روی فرم ورود، scraperها و آن اسکریپت اشتباهی که API شما را می‌کوبد در اختیار دارید — و ساده‌ترین چیزی که می‌شود اشتباه تنظیمش کرد، چون حدی که بیش از اندازه سفت باشد همان مشتری‌هایی را می‌بندد که قرار بود از آن‌ها محافظت کند. این راهنما می‌گوید عدد را چطور انتخاب کنید، کجا اعمالش کنید و چگونه کنار WAF و محافظت DDoS می‌نشیند.

Updated

Rate limiting: جلوی سوءاستفاده را بگیرید بدون مسدودکردن مشتری‌ها

واقعاً چه کاری می‌کند

هر بازدیدکننده درخواست می‌فرستد. یک rate limit می‌گوید: از یک کلاینت، در این تعداد ثانیه این تعداد درخواست را می‌پذیرم و هر چه فراتر از آن باشد رد می‌شود. کل ایده همین است — یک شمارنده که عاقبتی هم دارد.

آنچه آن را ارزشمند می‌کند عدم‌تقارن است. یک scraper، یک اسکریپت credential-stuffing یا یک اینتگریشن از کنترل خارج‌شده، در سطح یک درخواست منفرد دقیقاً شبیه یک مرورگر به نظر می‌رسند؛ با بازرسی یک درخواست نمی‌توانید تشخیصشان دهید. اما رفتارشان در طول زمان کاملاً متفاوت است: یک انسان صفحه‌ای را می‌خواند و در دقیقه چند لینک باز می‌کند، درحالی‌که یک اسکریپت صدها درخواست می‌فرستد. Rate limiting به‌جای محتوا، رفتار را می‌گیرد و برای همین جلوی حملاتی را می‌گیرد که هیچ signatureای آن‌ها را نمی‌شناسد.

انتخاب عددی که آسیب نزند

اشتباه رایج این است که حد را از روی شهود انتخاب کنید. از آنچه ترافیک واقعی شما همین حالا انجام می‌دهد شروع کنید: به شلوغ‌ترین بازدیدکنندهٔ مشروعتان در یک ساعت عادی نگاه کنید و بعد حد را با فاصلهٔ راحتی بالاتر از آن بگذارید. حدی که فقط یک بات می‌تواند به آن برسد بی‌سروصدا کارش را می‌کند؛ حدی که یک مشتری مشتاق هم به آن می‌خورد، تیکت پشتیبانیای است که خودتان ساخته‌اید.

دو نکته شما را از بیشتر false positiveها نجات می‌دهد. اول، به یاد داشته باشید که چند نفر می‌توانند یک آدرس مشترک داشته باشند — یک دفتر، یک مدرسه، NAT یک اپراتور موبایل — پس حدی که برای «یک انسان» کالیبره شده یک ساختمان را جریمه می‌کند. دوم، ترافیک خودتان را فراموش نکنید: مانیتورینگ، health checkها، اینتگریشن یک شریک و CI شما همگی از تعداد کمی آدرس و با فرکانس بالا می‌آیند و اولین کلاینت‌های مشروعی هستند که یک حد جدید معمولاً می‌شکندشان.

عمداً شل شروع کنید. حدی که بعد از یک هفته تماشا سفت‌ترش می‌کنید خیلی ارزان‌تر از حدی است که بعد از شکایت یک مشتری شل‌ترش می‌کنید.

هر مسیری حد یکسانی نمی‌خواهد

یک عدد واحد برای کل سایت مصالحه‌ای است که هیچ‌کس از آن راضی نیست — به‌قدر کافی شل برای مرور یعنی روی فرم ورود بی‌فایده، و به‌قدر کافی سفت برای ورود یعنی صفحهٔ محصولِ خراب.

به این فکر کنید که یک درخواست چقدر برای شما هزینه دارد و سوءاستفاده از آن چه چیزی نصیب مهاجم می‌کند. endpointهای ورود، بازنشانی رمز و تسویه ارزان‌اند برای درخواست‌دادن و ارزشمندند برای حمله، پس سفت‌ترین حدها را می‌گیرند — آدم یک‌بار وارد می‌شود، نه چهل بار در دقیقه. endpointهای جست‌وجو و API سرویس‌دهی‌شان گران است و برای scrape جذاب‌اند: آن‌ها را بر اساس نیاز یک اینتگریشن واقعی محدود کنید. صفحات معمولی و فایل‌های استاتیک ارزان‌اند و آدم‌های واقعی زیاد استفاده‌شان می‌کنند، پس یا حدهای سخاوتمندانه می‌خواهند یا اصلاً حدی نمی‌خواهند، چون cache شبکه CDN همین حالا دارد جذبشان می‌کند.

در cdn.com.tr می‌توان محدودیت نرخ درخواست را هم در سطح کل حساب و هم به‌ازای هر قانون تحویل (delivery rule) تنظیم کرد و همین است که این کار را عملی می‌کند: یک قانون سفت که با مسیر ورود شما مطابقت دارد و یکی شل‌تر برای بقیهٔ سایت.

چرا edge جای درست این کار است

Rate limiting داخل اپلیکیشن شما کار می‌کند، به این معنا که کد اجرا می‌شود. اما تا وقتی اپ شما بتواند یک درخواست را بشمارد، از قبل کانکشن را پذیرفته، یک worker را اشغال کرده و احتمالاً به دیتابیس دست زده است — حمله همان منبعی را که می‌خواستید محافظت کنید از قبل هزینه کرده است. زیر یک سیل ترافیک، خودِ limiter بخشی از چیزی می‌شود که از پا درمی‌آید.

وقتی در edge اعمال شود، رد کردن نزدیک کلاینت اتفاق می‌افتد، پیش از آنکه ترافیک اصلاً به origin شما برسد. سرور شما هرگز آن را نمی‌بیند، پس هزینه‌اش هم مال شما نیست. به همین دلیل است که rate limiting در edge وقتی origin شما از قبل در تنگنا است همچنان کار می‌کند: این حد بر سر همان منابعی که از آن‌ها دفاع می‌کند رقابت نمی‌کند.

Rate limiting در برابر WAF در برابر محافظت DDoS

این سه به‌جای هم به کار می‌روند اما واقعاً کارهای متفاوتی می‌کنند.

Rate limiting می‌شمارد. می‌داند یک کلاینت چند وقت به چند وقت درخواست می‌دهد و هیچ نمی‌داند دنبال چه چیزی است. جلوی brute force، scraping و کوبیدن‌های ناخواسته را می‌گیرد.

WAF بازرسی می‌کند. درخواست را می‌خواند و آن‌هایی را که شبیه SQL injection، cross-site scripting یا یک اکسپلویت شناخته‌شده‌اند مسدود می‌کند — یک درخواست مخرب در همان تلاش اول گرفته می‌شود، هر قدر هم آهسته برسد.

محافظت DDoS جذب می‌کند. وقتی ترافیک آن‌قدر بزرگ باشد که حتی شمردنش هم شما را از پا دربیاورد، آن حجم باید با ظرفیت شبکه‌ای پخش‌شده در مکان‌های متعدد بلعیده شود.

هر سه را لازم دارید چون هرکدام نقطهٔ کور دیگری را می‌پوشاند: یک درخواست زیرکانه که یک شمارنده به آن دست تکان می‌دهد و ردش می‌کند، هزار درخواست بی‌آزارنما که WAF هیچ ایرادی در آن‌ها نمی‌بیند و یک میلیون درخواست که هیچ ماشین منفردی حتی نمی‌تواند ارزیابی‌شان کند. در cdn.com.tr این‌ها بخشی از یک edge واحدند و از یک پنل پیکربندی می‌شوند.

راه‌اندازی بدون خراب‌کردن چیزی

حد را آن‌قدر بالا بگذارید که انتظار داشته باشید هرگز فعال نشود، و بعد تماشا کنید. نگاه کنید واقعاً چه چیزی رد شده است: اگر یک scraper یا اسکریپت ورود بوده، با اطمینان سفت‌ترش کنید؛ اگر مانیتورینگ خودتان یا اینتگریشن یک مشتری بوده، تازه چیزی یاد گرفته‌اید پیش از آنکه به قیمت یک شکایت تمام شود.

استثناها را صادقانه و کم نگه دارید — مانیتورینگ خودتان و اینتگریشن‌های شریک شناخته‌شده، نه «هرکه بلندتر شکایت کرد». و با یک حد مثل عددی زنده رفتار کنید: ترافیک رشد می‌کند، یک اپ موبایل منتشر می‌شود، یک اینتگریشن نرخ polling خود را دو برابر می‌کند. حدی که پارسال سخاوتمندانه بود می‌تواند بی‌سروصدا دلیل خراب به نظر رسیدن یک قابلیت شود.

پرسش‌های پرتکرار

یک rate limit خوب برای شروع چقدر است؟

عدد جهانشمولی وجود ندارد — بستگی دارد کاربران واقعی شما چه می‌کنند. شلوغ‌ترین بازدیدکنندهٔ مشروع خود را در یک ساعت عادی اندازه بگیرید، حد را با فاصلهٔ راحتی بالاتر از آن بگذارید و تنها پس از تماشای آنچه رد می‌شود سفت‌ترش کنید. حدهای سفت جای‌شان روی مسیرهای ورود و بازنشانی رمز است، نه روی صفحات معمولی.

آیا rate limiting مشتری‌های واقعی را مسدود می‌کند؟

می‌تواند، اگر بیش از اندازه سفت تنظیم شود — به‌ویژه جایی که آدم‌های زیادی یک آدرس مشترک دارند (دفاتر، مدارس، شبکه‌های موبایل) یا جایی که مانیتورینگ و اینتگریشن‌های خودتان مرتب poll می‌کنند. شل شروع کردن و سفت‌کردن بر اساس ترافیک مشاهده‌شده تقریباً همهٔ این را از بین می‌برد.

آیا rate limiting برای متوقف‌کردن یک حملهٔ DDoS کافی است؟

نه. Rate limiting سوءاستفاده از سوی تعداد قابل‌مدیریتی کلاینت را مدیریت می‌کند. یک حملهٔ توزیع‌شده ترافیک را از منابعی به‌مراتب بیشتر از آن می‌فرستد که شمردن به‌تنهایی کمکی کند — آنجا به ظرفیت جذب DDoS جلوی origin نیاز دارید و rate limiting پشت آن کار ریزتر را انجام می‌دهد.

بهتر نیست به‌جایش داخل اپلیکیشن خودم rate limit بگذارم؟

حدهای سطح اپلیکیشن برای قواعد کسب‌وکاری به‌ازای هر حساب مفیدند («این پلن روزی ۱۰۰۰ فراخوان API دارد»). برای محافظت در برابر سوءاستفاده، edge بهتر است: درخواست پیش از رسیدن به سرور شما رد می‌شود، پس هیچ هزینه‌ای برای شما ندارد و وقتی origin شما زیر فشار است همچنان کار می‌کند.