حفاظت در برابر دیداس: چه چیزی در شبکه فیلتر میشود و چه به سرور میرسد
ساعت دو بامداد سایت برگشته، لود سرور بالا بوده، چند دقیقه اصلاً جواب نمیداده و حالا انگار عادی است. سؤال اول این نیست که «چطور جلوی حمله را بگیرم». سؤال اول این است: اصلاً حمله بود یا فقط بار زیاد؟ این مقاله همین را از روی لاگ وبسرور، جدول conntrack و الگوی درخواستها جدا میکند. بعد سه لایهی حمله را از هم تفکیک میکنیم و برای هر کدام میگوییم چه کاری از دست خودت برمیآید و کجا دیگر باید شبکهی بالادست کار کند. هر دستور قابل کپی است و خروجیاش را توضیح میدهیم.
اول بفهم حمله بود یا بار زیاد
قبل از هر کاری یک چیز را بپذیر: بدون خط پایه نمیشود قضاوت کرد. اگر نمیدانی سرورت در حالت سالم چند اتصال باز دارد و دقیقهای چند درخواست میگیرد، هر عددی ممکن است «زیاد» بهنظر برسد. پس اول چند دستور ساده بزن و عددها را با حس خودت از روزهای عادی مقایسه کن.
اتصالهای نیمهباز را بشمار. در یک SYN flood کلی اتصال در وضعیت SYN-RECV گیر میکند و به ESTABLISHED نمیرسد:
ss -n state syn-recv | wc -l
روی سرور سالم این عدد نزدیک صفر است. اگر صدها یا هزاران شد، نشانهی حملهی پروتکلی است، نه بار معمول.
جدول conntrack را نگاه کن. وقتی پر شود، کرنل بستههای جدید را دور میاندازد و سرویس از دید کاربر «قطع» میشود:
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
dmesg | grep -i conntrack
اگر count به max نزدیک شده و در dmesg خط nf_conntrack: table full, dropping packet دیدی، جدول پر شده. این خودش میتواند نتیجهی سیل اتصال باشد یا فقط ترافیک زیادِ قانونی روی سروری که سقف conntrackاش پایین مانده.
حالا سراغ لاگ وبسرور برو. پرتکرارترین IPها را دربیاور:
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
خروجی، تعداد درخواست کنار هر IP است. دو الگوی متفاوت میبینی. یکی دو IP با چند دههزار درخواست یعنی یک منبع پرسروصدا که با یک بلاک ساده تمام میشود. صدها IP که هر کدام چند صد درخواست زدهاند یعنی حملهی توزیعشده که بلاک دستی جوابش را نمیدهد.
ببین کدام مسیر زیر فشار است و کدها چه میگویند:
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
اگر یک مسیر گران مثل /?s=، /wp-login.php یا یک API جستوجو بیشتر ضربهها را میخورد و پر از 503 و 499 هستی، این ترافیک به سرورت رسیده و سرورت زیرش کم آورده. یعنی حملهی لایهی هفت یا بارِ واقعیِ بیش از توان. این دو را از روی توزیع User-Agent و الگوی زمانی تفکیک کن.
| نشانه | یعنی چه | چه چیزی را رد میکند |
|---|---|---|
هزاران SYN-RECV، کمِ ESTABLISHED | سیل پروتکلی (SYN flood) | بار لایهی هفت را رد میکند؛ درخواستها اصلاً کامل نمیشوند |
| یک IP با حجم عظیم | منبع واحد، بلاکپذیر | حملهی توزیعشده را رد میکند |
| صدها IP، هرکدام متوسط | حملهی توزیعشده یا باتنت | یک کلاینت خراب یا کراولر را رد میکند |
یک مسیر گران، پر از 5xx | لایهی هفت یا بارِ واقعی | سیل حجمی خالص را رد میکند؛ بستهها به اپ رسیدهاند |
| اوج ترافیک روی رابط، لود پایین اپ | سیل حجمی که لینک را پر کرده | مشکل نرمافزاری را رد میکند |
همین پنج خط اغلب جواب را میدهند. یادداشتش کن. دفعهی بعد خط پایهات را داری.
سه لایه، سه جای متفاوت برای فیلتر شدن
حملهها یکجور نیستند و مهمتر اینکه در جاهای متفاوتی جلویشان گرفته میشود. این تفکیک تعیین میکند کدام مشکل را خودت میتوانی حل کنی و کدام را نه.
| لایه | نمونه | کجا جلویش گرفته میشود | از دست تو چه برمیآید |
|---|---|---|---|
| حجمی (L3/L4) | سیل UDP، حملات تقویتی | شبکهی بالادست / scrubbing | تقریباً هیچ؛ لینک قبل از فایروال تو پر میشود |
| پروتکلی (L4) | SYN flood، ACK flood | کرنل و فایروال لبه | SYN cookies، تنظیم conntrack، محدودکردن نرخ SYN |
| لایهی هفت (L7) | سیل HTTP به مسیر گران | وبسرور و اپ خودت | limit_req، کش، بستن مسیرهای سنگین |
نکتهی تلخ دربارهی لایهی حجمی را همینجا بگویم. وقتی لینک ورودیات اشباع شود، بستهها قبل از اینکه فایروال سرورت آنها را ببیند پهنای باند را خوردهاند. به گفتهی Cloudflare، بزرگترین حملهای که در می ۲۰۲۵ خنثی کرد به ۷.۳ ترابیت بر ثانیه رسید، ۴۵ ثانیه طول کشید و ۳۷.۴ ترابایت داده فرستاد که نزدیک ۹۹٫۹۹۶٪ آن سیل UDP بود. هیچ تنظیم iptables روی یک سرور تک این حجم را جذب نمیکند. اینجاست که پاکسازی بالادستی تنها جواب است. سرور مجازی انگلستان ما در کاونتری روی چند دستگاه ۴۰۰ گیگابیتی فایروال سختافزاری دارد که ترافیک حملهی دیداس را پیش از رسیدن به سرورت پاکسازی میکند؛ یعنی لایهی حجمی و بخش زیادی از پروتکلی بالادست گرفته میشود و چیزی که به دست تو میرسد قابلمدیریتتر است.
پروتکلی: SYN flood و کاری که از دستت برمیآید
حملهی پروتکلی منابعِ وضعیت اتصال را خالی میکند، نه پهنای باند را. در SYN flood مهاجم دستدادن TCP را نیمهکاره رها میکند و صفِ اتصال نیمهباز پر میشود. سه کار از روی خود سرور شدنی است.
SYN cookies را روشن کن تا کرنل وقتی صف پر شد بدون نگهداشتن وضعیت پاسخ دهد:
sysctl -w net.ipv4.tcp_syncookies=1
هزینهاش را صادقانه بگویم: SYN cookies بعضی گزینههای TCP را روی آن دستدادن محدود میکند، پس این را دائمی روشن نگهندار اگر لازم نیست، فقط بهعنوان سوپاپ اطمینان زیر فشار. در کرنلهای امروزی تنها وقتی صف سرریز کند فعال میشود.
تایماوت اتصالهای نیمهباز را پایین بیاور تا جدول conntrack زودتر خالی شود. مقدار پیشفرض nf_conntrack_tcp_timeout_syn_recv در netfilter شصت ثانیه است که زیر سیل، خیلی زیاد است:
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_syn_recv=15
و نرخ بستههای SYN را در فایروال سقف بزن:
iptables -A INPUT -p tcp --syn -m limit --limit 50/s --limit-burst 100 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
یک هشدار جدی: اینها فقط وقتی کمک میکنند که پهنای باند ورودیات هنوز اشباع نشده باشد. اگر سیل آنقدر بزرگ است که لینک را پر کرده، فایروال تو دیگر فرصت دیدن بسته را ندارد. آن وقت باید بس کنی و سراغ بالادست بروی.
لایهی هفت: سختترین، چون شبیه ترافیک واقعی است
این لایه دشوار است چون درخواستها قانونی بهنظر میرسند: یک GET معتبر به یک صفحهی واقعی. فرقش با کاربر این است که در حجم بالا و روی گرانترین مسیرها تکرار میشود. طبق گزارش فصلی Cloudflare، حملات مبتنی بر HTTP در فصل دوم ۲۰۲۵ نسبت به سال قبلش ۱۲۹٪ رشد داشتند و ۷۱٪شان از باتنتهای شناختهشده آمدند. سه کار عملی داری.
نرخ درخواست را محدود کن
در nginx با ماژول limit_req روی هر IP سقف بگذار. در بخش http:
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
و روی مسیر گران:
location /search/ {
limit_req zone=perip burst=20 nodelay;
}
یعنی بهطور میانگین ۱۰ درخواست در ثانیه برای هر IP، با تحملِ یک انفجار کوتاه تا ۲۰ تا. درخواست مازاد بهصورت پیشفرض کد 503 میگیرد (قابل تغییر با limit_req_status). برای نرخ کمتر از یک در ثانیه از r/m استفاده کن، مثلاً 30r/m.
یک تلهی رایج: اگر سرورت پشت یک CDN یا پراکسی است، $binary_remote_addr آدرس پراکسی را میبیند نه کاربر واقعی، و همه را با یک سطل محدود میکنی. باید IP واقعی را از X-Forwarded-For با set_real_ip_from دربیاوری، وگرنه نرخدهیات بیمعنی است.
بار را با کش بردار
بیشتر سیلهای لایهی هفت یک صفحهی داینامیک را میکوبند که هر بار دیتابیس را درگیر میکند. اگر همان صفحه کش شود، درخواست تکراری دیگر به اپ و دیتابیس نمیرسد. سیدیان ابریشم محتوای ایستا را از نزدیکترین نود سرو میکند و اجازه میدهد قواعد امنیتی و محدودسازی دسترسی را از پنل برای دامنهات تنظیم کنی، که بارِ درخواستهای تکراری را از سرور مبدأ برمیدارد. صادق باشم: صفحهی محصولِ سیدیان ما ادعای «محافظت دیداس» نمیکند و فعلاً در دورهی آزمایشی است؛ کاری که میکند جذب و کش و اعمال قاعدهی دسترسی است، نه scrubbing حجمی. برای همان کار هم ارزشش را دارد.
مسیرهای گران را ببند
هر مسیری که بیاستفاده است و گران است را خاموش کن. در وردپرس xmlrpc.php و تلاش روی wp-login.php هدفهای همیشگیاند. اگر ازشان استفاده نمیکنی، در nginx ببندشان:
location = /xmlrpc.php { deny all; }
جستوجوی داخلی، صفحهبندی عمیق و فیلترهای ترکیبی هم مسیرهای گراناند. زیر فشار، موقتاً محدود یا کششان کن.
کی باید دست بکشی
اگر گراف رابط شبکه نشان میدهد ترافیک ورودی به سقف پورت سرورت چسبیده و لود اپ پایین است، پیام روشن است: پهنای باندت پر شده و بستهها قبل از سرورت مصرف شدهاند. اینجا دیگر هیچ قاعدهی iptables یا nginx کمکت نمیکند. وقتت را تلف نکن. تنها راه، پاکسازی در شبکهی بالادست است، چه با فایروال سختافزاری مرکز داده و چه با قرار دادن یک لایهی لبه جلوی مبدأ. دانستن این لحظه، خودش نیمی از کار است.
کجا این را اجرا کنیم
اگر کارت به جایی رسیده که مرتب درگیر سیل حجمی و پروتکلی هستی، پاکسازی بالادست را باید بخری، نه اینکه روی سرور شبیهسازی کنی. سرور مجازی انگلستان در کاونتری همین را میدهد: فایروال سختافزاری روی دستگاههای ۴۰۰ گیگابیتی که ترافیک حمله را پیش از سرور پاک میکند، پورت ۱۰ گیگابیتی برای هر سرور و تضمین ۹۹٫۹٪ در دسترس بودن. لایهی هفت را بعد از آن خودت با limit_req و کش مهار میکنی. برای برداشتن بار درخواستهای تکراری و اعمال قاعدهی دسترسی روی دامنه، سیدیان ابریشم را جلوی مبدأ بگذار؛ با این آگاهی که این سرویس کش و کنترل دسترسی است، نه سپر حجمی. اگر همزمان با اینها هستهی مجازی برای پردازش لایهی هفت کم آوردی، سراغ سرور اختصاصی رفتن منطقیتر از بزرگکردن بیپایان VPS است. و پیش از هر چیز، سرور را سفت کن؛ راهنمای سختسازی سرور اوبونتو در ۳۰ دقیقه نقطهی شروع خوبی است.
منابع
- NGINX ngx_http_limit_req_module documentation (unknown)
- Cloudflare blocks a monumental 7.3 Tbps DDoS attack (2025-06)
- Cloudflare DDoS threat report for 2025 Q2 (2025-07)
- DDoS Attack Types & Mitigation Methods (Imperva) (unknown)
پرسشهای پرتکرار
چطور بفهمم حملهی دیداس بوده یا فقط بار زیاد؟
با مقایسه با خط پایهی سرور سالم. اتصالهای نیمهباز را با «ss -n state syn-recv | wc -l» بشمار، پرتکرارترین IPها و مسیرها را از access.log دربیاور و کدهای وضعیت را نگاه کن. هزاران SYN-RECV یعنی سیل پروتکلی؛ چند IP با حجم عظیم یعنی منبع بلاکپذیر؛ یک مسیر گرانِ پر از 503 یعنی لایهی هفت یا بار واقعی بیش از توان.
آیا با فایروال خود سرور میتوانم جلوی حملهی حجمی را بگیرم؟
نه، وقتی لینک ورودی اشباع شده باشد. بستهها پیش از رسیدن به فایروال سرورت پهنای باند را پر میکنند، پس iptables فرصت دیدنشان را ندارد. حملهی حجمی باید در شبکهی بالادست یا با scrubbing مرکز داده پاک شود. کار سرور فقط لایهی پروتکلی سبک و لایهی هفت است.
دستور limit_req در nginx چه کد وضعیتی برمیگرداند؟
بهصورت پیشفرض 503 برای درخواستهای مازاد بر نرخ تعیینشده. با دستور limit_req_status میتوانی عوضش کنی. نرخ را با r/s میدهی و برای کمتر از یک در ثانیه از r/m استفاده میکنی، مثل 30r/m؛ burst هم یک انفجار کوتاه را تحمل میکند.
روشنکردن SYN cookies چه هزینهای دارد؟
بعضی گزینههای TCP روی آن دستدادن محدود میشوند. در کرنلهای امروزی net.ipv4.tcp_syncookies تنها وقتی صف اتصال سرریز کند فعال میشود، پس بهعنوان سوپاپ اطمینان زیر فشار بیخطر است و بیشترِ زمان اثری ندارد.
سیدیان جلوی دیداس را میگیرد؟
صفحهی محصول سیدیان ابریشم ادعای محافظت دیداس نمیکند و فعلاً در دورهی آزمایشی است. کاری که میکند کشکردن محتوا از نود نزدیک و اعمال قاعدهی امنیتی و محدودسازی دسترسی از پنل است، که بار درخواستهای تکراری را از مبدأ برمیدارد. برای پاکسازی ترافیک حجمی باید روی فیلتر بالادست مرکز داده حساب کنی.