سایت کند شده، لاگ سرور پر از درخواستهای تکراری از یک IP است، و کاربران واقعی هم در همین حین صفحه را نیمهکاره رها میکنند. اگر همین حالا به این نقطه رسیدهاید، احتمالاً به محدودیت نرخ فکر میکنید. اما قبل از اینکه یک قانون ساده در Nginx بنویسید و آن را روی کل سایت اعمال کنید، باید بدانید که این ابزار دولبه است. تنظیم اشتباه آن میتواند ترافیک سالم شما را هم قطع کند.
ربات مفید و ربات مضر را چطور از هم تشخیص دهیم؟
اولین اشتباهی که میبینم این است که همه رباتها یکجا مسدود میشوند. رباتهای موتور جستجو مثل Googlebot و Bingbot باید بتوانند آزادانه سایت شما را بخزند. اگر آنها را محدود کنید، رتبه سایت در نتایج جستجو افت میکند و چند هفته بعد متوجه میشوید که ترافیک ارگانیک نصف شده است.
راه تشخیص، بررسی User-Agent و تأیید IP است. گوگل لیست رسمی IPهای خود را منتشر میکند. یک ربات مفید معمولاً:
- از IPهای اعلامشده و ثابت میآید.
- رفتار قابل پیشبینی دارد و صفحات را با فاصله منطقی میخواند.
- robots.txt را رعایت میکند.
در مقابل، ربات مضر (اسکرپر، باتهای تست رمز عبور، یا ابزارهای استخراج محتوا) معمولاً User-Agent جعلی دارد، از IPهای متغیر میآید، و در بازههای کوتاه درخواستهای انفجاری میفرستد. برای دیدن الگوی واقعی، لاگ را با این دستور بررسی کنید:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
این دستور ۲۰ IP پرترافیک را نشان میدهد. اگر یک IP در یک ساعت ۵۰۰۰ درخواست فرستاده باشد، آن یک ربات مضر است، نه یک کاربر پشت مرورگر.
محدودیت نرخ را کجا اعمال کنیم؟
جای اعمال محدودیت نرخ به اندازه خود محدودیت مهم است. سه لایه وجود دارد و هر کدام کاربرد خودش را دارد.
لایه اول: وبسرور (Nginx یا Apache)
این نزدیکترین لایه به ترافیک است و سریعترین پاسخ را میدهد. در Nginx با ماژول limit_req این کار انجام میشود:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
location /login/ {
limit_req zone=mylimit burst=5 nodelay;
limit_req_status 429;
}
}
این تنظیم میگوید هر IP حداکثر ۱۰ درخواست در ثانیه میتواند بفرستد، با اجازه ۵ درخواست اضافه بهصورت burst. کد وضعیت 429 بهجای 403 برگردانده میشود تا کلاینت بفهمد موقتاً محدود شده، نه اینکه دسترسیاش ممنوع است.
لایه دوم: فایروال یا CDN
اگر ترافیک شما از CDN عبور میکند، محدودیت را همانجا اعمال کنید. مزیتش این است که درخواستهای مضر حتی به سرور شما نمیرسند و پهنای باند مصرف نمیکنند. برای سناریوهای حمله حجمی، ترکیب این لایه با محافظت در برابر DDoS منطقیتر است تا اینکه بخواهید همهچیز را روی یک سرور تنها مدیریت کنید.
لایه سوم: اپلیکیشن
محدودیت در سطح کد (مثلاً در PHP یا Python) انعطاف بیشتری میدهد. میتوانید بر اساس کاربر لاگینشده، نه فقط IP، محدودیت تعریف کنید. اما هزینهاش این است که درخواستهای مضر تا لایه اپلیکیشن میآیند و منابع سرور را مصرف میکنند. این لایه را برای محافظت از endpointهای حساس مثل ورود و ثبتنام نگه دارید، نه برای کل سایت.
اینجا اشتباه میکنند
بزرگترین اشتباهی که در عمل دیدهام، اعمال محدودیت نرخ روی کل سایت با یک نرخ بسیار پایین است. مثلاً کسی rate=2r/s را روی همه مسیرها میگذارد. نتیجه؟ کاربری که یک صفحه را باز میکند و مرورگرش ۱۵ درخواست همزمان برای CSS، JS و تصاویر میفرستد، بلافاصله خطای 429 میگیرد. سایت برای او ناقص بالا میآید، تصاویر لود نمیشوند، و فکر میکند سایت خراب است.
علامتش هم واضح است: در لاگ، خطای 429 برای درخواستهای .css و .js ثبت میشود، نه برای صفحات اصلی. اگر این الگو را دیدید، محدودیت را از روی فایلهای استاتیک بردارید و فقط روی endpointهای پویا اعمال کنید.
هزینه مسدودسازی بیش از حد
هر محدودیتی که اعمال میکنید، یک هزینه دارد: ممکن است کاربر واقعی را هم بیرون کند. کاربرانی که از شبکههای اشتراکی (اداری، دانشگاهی، یا پشت NAT اپراتور موبایل) میآیند، همه یک IP دارند. اگر محدودیت را بر اساس IP بگذارید، یک کاربر پرمصرف میتواند بقیه را قربانی کند.
راهحل این است که محدودیت را بر اساس ترکیب IP و مسیر تعریف کنید، نه فقط IP. برای مسیرهای حساس مثل /login سختگیرانهتر عمل کنید و برای صفحات عمومی سخاوتمندانهتر. یک جدول ساده از تصمیمها:
| مسیر | نرخ پیشنهادی | دلیل |
|---|---|---|
| /login | 5r/m | جلوگیری از تست رمز عبور |
| /api/search | 20r/s | محافظت از دیتابیس |
| صفحات عمومی | بدون محدودیت | تجربه کاربری |
| فایلهای استاتیک | بدون محدودیت | لود طبیعی مرورگر |
نکتهای که کمتر به آن توجه میشود: محدودیت نرخ جایگزین احراز هویت نیست. اگر endpoint ورود شما در برابر حمله دیکشنری آسیبپذیر است، محدودیت نرخ فقط سرعت حمله را کم میکند، نه اینکه جلوی آن را بگیرد. باید کنارش قفل حساب بعد از چند تلاش ناموفق و احراز هویت دو مرحلهای هم داشته باشید.
چطور بفهمیم محدودیت درست کار میکند؟
بعد از اعمال تنظیمات، باید دو چیز را اندازه بگیرید. اول، نرخ خطای 429 در لاگ. اگر این عدد ناگهان بالا رفت، یعنی محدودیت بیش از حد سختگیرانه است. دوم، زمان پاسخ سرور (TTFB). اگر محدودیت درست کار کند، TTFB باید پایین بیاید چون درخواستهای مضر دیگر به بکاند نمیرسند.
برای تست، از ابزارهایی مثل ab یا wrk استفاده کنید و رفتار سایت را زیر بار شبیهسازی کنید:
ab -n 1000 -c 50 https://example.com/login/
اگر بعد از این تست، سایت برای کاربران عادی کند شد یا خطا داد، محدودیت شما بیش از حد تهاجمی است. برای بررسی سلامت زیرساخت در همین لحظه، وضعیت لحظهای سرویسها را چک کنید تا مطمئن شوید مشکل از محدودیت است، نه از سرور.
یک نکته عملی: لاگهای محدودیت نرخ را حتماً نگه دارید. اگر بعداً بخواهید بفهمید چه کسی و چه زمانی حمله کرده، این لاگها تنها منبع شما هستند. درباره اهمیت نگهداری لاگها در لاگ ممیزی چیست و چگونه آن را دستنخورده نگه داریم؟ بیشتر توضیح دادهام.
پرسشهای پرتکرار
تفاوت محدودیت نرخ و محدودیت همزمانی چیست؟
محدودیت نرخ تعداد درخواست در واحد زمان را کنترل میکند (مثلاً ۱۰ درخواست در ثانیه)، در حالی که محدودیت همزمانی تعداد اتصالهای باز همزمان را محدود میکند. برای مقابله با رباتهای اسکرپر، محدودیت نرخ مؤثرتر است. برای جلوگیری از اشغال منابع توسط یک کلاینت، محدودیت همزمانی کارسازتر است. در عمل، هر دو را با هم استفاده کنید.
آیا محدودیت نرخ روی Googlebot هم اعمال میشود؟
بله، اگر قانون شما بر اساس IP باشد و IP گوگل را استثنا نکنید، Googlebot هم محدود میشود. این کار باعث افت رتبه سایت میشود. راه درست این است که IPهای رسمی گوگل را در لیست سفید قرار دهید یا از تأیید معکوس DNS استفاده کنید تا فقط ربات واقعی گوگل از محدودیت معاف شود.
چرا بعد از اعمال محدودیت نرخ، کاربران از خطای 429 شکایت میکنند؟
معمولاً به این دلیل که نرخ را برای کل سایت و بدون در نظر گرفتن فایلهای استاتیک تنظیم کردهاید. مرورگر برای نمایش یک صفحه واحد دهها درخواست میفرستد. محدودیت را روی مسیرهای پویا و حساس اعمال کنید و فایلهای CSS، JS و تصاویر را از آن معاف کنید.
محدودیت نرخ را در Nginx بهتر تنظیم کنیم یا در CDN؟
اگر ترافیک شما از CDN عبور میکند، اعمال محدودیت در CDN بهتر است چون درخواستهای مضر به سرور شما نمیرسند و منابع ذخیره میشود. اما اگر کنترل دقیقتری روی منطق اپلیکیشن نیاز دارید (مثلاً محدودیت بر اساس کاربر لاگینشده)، لایه Nginx یا خود اپلیکیشن گزینه بهتری است. بهترین نتیجه از ترکیب هر دو لایه بهدست میآید.
اگر همین حالا با حمله ربات مواجه هستید و نمیدانید از کجا شروع کنید، اول لاگ را بررسی کنید، سپس محدودیت را فقط روی مسیرهای حساس اعمال کنید، و بعد از هر تغییر رفتار سایت را اندازه بگیرید. برای سناریوهای پیچیدهتر یا حملات حجمی، خدمات امنیت سرورنت میتواند لایههای دفاعی را بدون درگیر کردن شما با تنظیمات دستی فراهم کند.
دیدگاهها ۰
هنوز دیدگاهی ثبت نشده؛ اولین نفر باشید!