می‌خواهیم تعداد درخواست سریع هر مبدأ را کنترل کنیم، بدون آنکه ابتدا رفتار کاربران را حدس بزنیم. امشب zone، burst و حالت مشاهده را با پاسخ واقعی آزمایش می‌کنیم.

این جلسه بخشی از دورهٔ انجین‌اکس در ۵۰ شب است. قرارداد آزمایشگاه، مسیرها و روال اعمال تغییر در راهنمای دوره آمده است.

محیط: www، realip مورد اعتماد درست، ماژول limit_req و فایل ثابت rate-lab.txt. آزمایش محدود فقط روی lab است.

bucket مشترک کارگرها#

در HTTP_LAB:

limit_req_zone $binary_remote_addr zone=per_ip:10m rate=5r/s;
log_format rate_lab '$remote_addr $status $limit_req_status $uri';

zone حافظهٔ مشترک وضعیت کلیدها را نگه می‌دارد؛ binary_remote_addr شکل کم‌حجم آدرس است. اگر پشت NAT باشی، چند کاربر این bucket را شریک می‌شوند. IP اعلام‌شدهٔ مهاجم نباید کلید را کنترل کند.

در server:

location = /rate-lab.txt {
    limit_req zone=per_ip burst=5 nodelay;
    limit_req_dry_run on;
    limit_req_status 429;
    access_log /var/log/nginx/rate-lab.log rate_lab;
    try_files $uri =404;
}

burst ظرفیت موج اضافه است؛ nodelay درخواست‌های مجاز burst را به تأخیر صف نمی‌اندازد و اضافه‌تر رد می‌شود. dry run رفتار را ثبت ولی مسدود نمی‌کند. برای تست از return فوری استفاده نکن؛ بعضی مراحل پردازش پیش از limiter تمام می‌شوند. فایل باید واقعاً توسط handler سرو شود.

مشاهده سپس اجرا#

روی وب‌سرور فایل را با printf '%s\n' 'rate lab OK' | sudo tee /var/www/nginx-lab/public/rate-lab.txt >/dev/null بساز. پس از validate/reload، روی کلاینت ۲۰ موج کوچک زیر را اجرا کن:

for LAB_REQUEST in {1..20}; do
  curl --silent --show-error --cacert ~/nginx-lab/pki/ca.crt \
    --resolve www.nginx.test:443:192.168.57.10 \
    --output /dev/null --write-out '%{http_code}\n' \
    https://www.nginx.test/rate-lab.txt
done

در rate-lab.log باید وضعیت‌هایی مثل REJECTED_DRY_RUN ببینی ولی پاسخ فایل سالم بماند. سپس dry_run را off کن، test/reload بگیر و پس از فروکش موج قبلی همان آزمون را تکرار کن؛ باید بخشی از درخواست‌های بیش از ظرفیت 429 شوند. تعداد دقیق به سرعت ارسال وابسته است. در کلاینت آهسته اگر هیچ excess ایجاد نشد، سرعت درخواست را ثبت کن و با concurrency کوچک کنترل‌شده آزمایش کن؛ تعداد زیاد بی‌هدف نفرست.

درخواست‌های با فاصلهٔ مناسب و IP دوم را هم بررسی کن؛ نباید صرفاً موج آزمون اول را ادامه بدهی. همهٔ مسیرهای WordPress یا API نرخ یکسان نمی‌خواهند.

بازگشت: ابتدا به dry run برگرد، سپس تنظیم محل را بردار. rate limit کنترل نرخ است؛ احراز هویت، WAF و دفاع DDoS حجمی را جایگزین نمی‌کند.

منبع: limit_req .