جلوگیری از حملات DDoS: تشخیص حمله و مقابله با آن روی سرور لینوکس
سرور کند شده، سایتها دیر بالا میآیند یا اصلاً باز نمیشوند و لود سرور بیدلیل بالا رفته است. اولین چیزی که به ذهن میرسد حمله DDoS است، اما قبل از اجرای هر دستوری باید مطمئن شوید واقعاً حملهای در جریان است؛ یک اسکریپت خراب، یک کوئری سنگین دیتابیس یا یک بکاپگیری بدموقع هم دقیقاً همین نشانهها را میسازد و درمانشان کاملاً فرق میکند.
در ادامه، اول روش تشخیص حمله و بعد لایهبهلایه راههای مقابله با آن روی یک سرور لینوکسی آمده است. دستورها برای توزیعهای امروزی (AlmaLinux، Rocky Linux، CentOS Stream، Ubuntu و Debian) نوشته شدهاند و هرجا روش قدیمی هنوز در اینترنت پیدا میشود، معادل درست امروزیاش هم آمده است.
یک هشدار قبل از شروع: تمام کارهای این مقاله فایروال و وبسرور را دستکاری میکنند و یک اشتباه میتواند دسترسی SSH خودتان را ببندد. پیش از اجرای هر دستور، مطمئن شوید یک راه دسترسی جایگزین (کنسول KVM، IPMI یا Rescue Mode سرویسدهنده) در اختیار دارید و از فایلهای کانفیگی که ویرایش میکنید نسخه پشتیبان گرفتهاید.
گام اول: مطمئن شوید واقعاً حمله در جریان است
شمردن اتصالهای باز
سادهترین نشانه یک حمله در لایه اتصال، تعداد غیرعادی کانکشن باز روی پورت وب است. ابزار استاندارد امروز برای این کار ss است:
# تعداد اتصالهای برقرارشده روی پورت 80 و 443
ss -H -tn state established '( sport = :80 or sport = :443 )' | wc -l
# پرتکرارترین آیپیها بر اساس تعداد اتصال
ss -H -tn state connected | awk '{print $4}' | sed 's/:[^:]*$//' | sort | uniq -c | sort -rn | head -20
# نشانه SYN Flood: تعداد زیاد اتصال در وضعیت SYN-RECV
ss -H -tn state syn-recv | wc -l
دو نکته درباره این دستورها: سوئیچ -H سطر عنوان جدول را حذف میکند تا خروجی wc -l دقیقاً برابر تعداد اتصالها باشد (روی نسخههای خیلی قدیمی iproute2 که این سوئیچ را ندارند، یک واحد از عدد کم کنید). و در دستور دوم، sed 's/:[^:]*$//' فقط شماره پورت انتهایی را جدا میکند؛ برخلاف cut -d: -f1 که آدرسهای IPv6 را خراب میکند.
دستورهای قدیمیتر با netstat هنوز همین کار را میکنند و اگر روی سرور در دسترس بود میتوانید از آنها استفاده کنید، اما توجه داشته باشید netstat بخشی از بسته منسوخشده net-tools است و روی نصبهای تازه معمولاً اصلاً وجود ندارد:
netstat -anp | grep 'tcp|udp' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
netstat -n | grep :80 | wc -l
نسخه کاملتر همین بررسی، همراه با تفکیک وضعیت اتصالها و پورتها، در مشاهده تعداد کانکشنها و پیدا کردن آیپی مهاجم آمده است.
عدد جادویی وجود ندارد
در نوشتههای قدیمی میخوانید که «بالای ۳۵۰ تا ۵۰۰ کانکشن یعنی حمله». این فقط یک قاعده سرانگشتی است و بهتنهایی قابل اتکا نیست: روی سروری که چند سایت پربازدید میزبانی میکند، ۵۰۰ اتصال همزمان کاملاً عادی است؛ و روی یک سرور کمترافیک، ۱۰۰ اتصال همزمان از یک آیپی واحد قطعاً غیرعادی است.
معیار درست، عدد عادی خود سرور شماست. همین امروز که حملهای در کار نیست، خروجی دستورهای بالا را در ساعتهای شلوغ و خلوت یادداشت کنید تا مبنای مقایسه داشته باشید. دو چیز بیش از عدد کل مهم است:
- توزیع اتصالها: اگر ۳۰۰ اتصال از ۳۰۰ آیپی مختلف باشد یعنی ترافیک عادی؛ اگر ۳۰۰ اتصال از ۵ آیپی باشد یعنی مشکل.
- وضعیت اتصالها: انبوه اتصال در وضعیت
SYN-RECVنشانه SYN Flood است، و انبوه اتصال در وضعیتESTABLISHEDکه هیچ دادهای رد و بدل نمیکنند نشانه حملههای کندکننده مثل Slowloris.
آیپی مهاجم و مسئله موقعیت جغرافیایی
پس از پیدا کردن آیپیهای پرتکرار میتوانید کشور آنها را با سرویسهایی مثل ip2location.com بررسی کنید. اما به دو نکته دقت کنید تا مشتری واقعی خودتان را قطع نکنید:
- «ایرانی نبودن آیپی» بهتنهایی دلیل حمله نیست. اگر سایت شما از CDN یا پروکسی معکوس استفاده میکند، همه ترافیک با آیپی خارجی همان سرویس به سرور میرسد و بلاک کردن آن یعنی از دسترس خارج شدن کل سایت.
- در حملههای بزرگ، ترافیک از باتنتی با هزاران آیپی میآید و در حملههای SYN Flood آیپی مبدأ اصولاً جعلی (spoofed) است؛ یعنی بلاک کردن تکتک آیپیها بیفایده است و باید سراغ محدودسازی نرخ رفت.
آیا اصلاً کاری از دست سرور برمیآید؟
این را قبل از هر تنظیمی روشن کنید: اگر حجم ترافیک حمله از ظرفیت پورت شبکه سرور بیشتر باشد، پورت پیش از رسیدن بستهها به فایروال اشباع شده است و هیچ قانون iptables یا CSF کمکی نمیکند، چون بستهها اصلاً به سرور نمیرسند. در این حالت تنها راه، فیلتر شدن ترافیک در بالادست است: با پشتیبانی سرویسدهنده یا دیتاسنتر خود تماس بگیرید و از سرویسهای محافظت در برابر DDoS یا یک CDN جلوی سایت استفاده کنید. تمام روشهای بعدی این مقاله برای حملههایی مؤثرند که سرور توان دریافتشان را دارد ولی توان پردازششان را ندارد.
گام دوم: تنظیم CSF (سریعترین و مؤثرترین کار)
اگر CSF (ConfigServer Security & Firewall) روی سرور نصب است، بیشتر کاری که لازم دارید با چند گزینه در فایل تنظیماتش انجام میشود. اول یک نسخه پشتیبان بگیرید و بعد فایل را باز کنید:
cp /etc/csf/csf.conf /etc/csf/csf.conf.bak vi /etc/csf/csf.conf
دقت کنید که نحو (syntax) این فایل بهصورت NAME = "VALUE" است. مقدارها را با دو نقطه (:) ننویسید؛ نوشتههای قدیمی این را اشتباه نقل کردهاند و CSF چنین خطی را نمیخواند. شکل درست این است:
PS_INTERVAL = "90" PS_LIMIT = "10" PORTFLOOD = "80;tcp;20;4"
معنای این سه گزینه:
- PS_INTERVAL و PS_LIMIT مربوط به تشخیص پورتاسکناند: در بازه ۹۰ ثانیه، اگر یک آیپی بیش از ۱۰ بار به پورتهای بسته بخورد بلاک میشود. مقدار
0برای PS_INTERVAL یعنی غیرفعال. برای اینکه این قابلیت کار کند بایدPS_PORTSهم تعریف شده باشد. - PORTFLOOD قالب
پورت;پروتکل;تعداد;ثانیهدارد. مقدار بالا یعنی «اگر یک آیپی در ۴ ثانیه بیش از ۲۰ اتصال به پورت ۸۰ TCP باز کرد، بلاکش کن».
دو گزینه دیگر هم هستند که در عمل بیشترین اثر را روی حملههای HTTP دارند:
CT_LIMIT = "100" CT_INTERVAL = "30" CT_BLOCK_TIME = "1800" CT_PERMANENT = "0" CT_PORTS = "80,443" CONNLIMIT = "80;30,443;30"
- CT_LIMIT (Connection Tracking) هر
CT_INTERVALثانیه اتصالها را میشمارد و آیپیای که بیش از حد تعیینشده اتصال همزمان داشته باشد را بلاک میکند. حتماًCT_PERMANENT = "0"بگذارید تا بلاک موقت باشد و بعد ازCT_BLOCK_TIME(اینجا ۱۸۰۰ ثانیه) خودبهخود برداشته شود؛ وگرنه بلاکها دائمی میشوند و بهمرور کاربران واقعی را هم از دست میدهید. مقدارCT_INTERVALرا زیر ۳۰ ثانیه نگذارید، چون شمارش مکرر خودش به سرور بار میآورد. کاری که این گزینه میکند دقیقاً همان کاری است که اسکریپتهای جانبی مثل DDoS-Deflate انجام میدادند، منتها بهصورت بومی و پشتیبانیشده. - CONNLIMIT سقف اتصال همزمان هر آیپی به هر پورت را تعیین میکند؛ مقدار بالا یعنی هر آیپی حداکثر ۳۰ اتصال همزمان به پورت ۸۰ و ۳۰ اتصال به ۴۴۳.
گزینه SYNFLOOD هم وجود دارد، ولی آن را فقط زمانی روشن کنید که واقعاً زیر SYN Flood هستید؛ خود مستندات CSF هشدار میدهد که این قابلیت پرهزینه است و روی سرور بدون حمله، سرعت برقراری همه اتصالها را پایین میآورد.
قبل از ریاستارت، خودتان را قفل بیرون نکنید. این گزینهها اتصالها را بر اساس تعداد میبندند و اگر شما و همکارانتان پشت یک آیپی مشترک (NAT دفتر) باشید، ممکن است خودتان قربانی شوید. آیپی خودتان، آیپی سرویس مانیتورینگ و آیپی سرویسهای پرداخت را در لیست سفید بگذارید و مطمئن شوید پورت SSH سرور در TCP_IN هست:
csf -a 203.0.113.10 admin office
بعد از هر تغییر در csf.conf حتماً فایروال را ریاستارت کنید و مطمئن شوید حالت آزمایشی خاموش است (یعنی TESTING = "0")، وگرنه قوانین هر بار پاک میشوند:
csf -r
اگر مطمئن نیستید تنظیماتتان درست است، عمداً TESTING را روی "1" بگذارید و اول قوانین را آزمایش کنید؛ در این حالت یک کرانجاب هر پنج دقیقه فایروال را پاک میکند و اگر دسترسی خودتان قطع شد، حداکثر پنج دقیقه بعد برمیگردد.
گام سوم: مسدود کردن دستی آیپی مهاجم
پیش از بلاک کردن هر آیپی، یک بار مطمئن شوید که آن آیپی متعلق به خودتان، به CDN یا پروکسی جلوی سایت، به سرویس مانیتورینگ یا به درگاه پرداخت نیست. بستن آیپی CDN یعنی خاموش کردن کل سایت با دست خودتان.
اگر CSF دارید، سادهترین و ماندگارترین راه همین است (بلاک پس از ریبوت هم باقی میماند):
csf -d 218.92.207.28 DDoS attack # بررسی اینکه یک آیپی بلاک شده یا نه csf -g 218.92.207.28 # برداشتن بلاک csf -dr 218.92.207.28
اگر CSF ندارید، مستقیم با iptables:
iptables -I INPUT -s 218.92.207.28 -j DROP
نکته مهم درباره ماندگاری قانون: دستور قدیمی service iptables save فقط روی CentOS 6 و روی سیستمهایی که بسته iptables-services نصب دارند کار میکند. روی سیستمهای امروزی:
# Debian / Ubuntu (بسته iptables-persistent) netfilter-persistent save # AlmaLinux / Rocky / CentOS با بسته iptables-services iptables-save > /etc/sysconfig/iptables systemctl restart iptables # اگر firewalld فعال است، بهجای iptables از این استفاده کنید firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="218.92.207.28" drop' firewall-cmd --reload
حواستان باشد که این سه روش را با هم قاطی نکنید؛ اگر firewalld فعال است، قوانینی که مستقیم با iptables اضافه کنید با اولین firewall-cmd --reload از بین میروند. اگر CSF نصب است هم قانون دستی iptables با اولین csf -r پاک میشود، پس روی سرور دارای CSF از csf -d استفاده کنید نه از iptables.
وقتی تعداد آیپیها زیاد شد، اضافه کردن صدها قانون جداگانه به iptables خودش سرور را کند میکند. راه درست ipset است:
ipset create ddos hash:ip hashsize 4096 timeout 3600 iptables -I INPUT -m set --match-set ddos src -j DROP ipset add ddos 218.92.207.28
گزینه timeout 3600 باعث میشود آیپیها بعد از یک ساعت خودبهخود آزاد شوند؛ این جلوی انباشته شدن بلاکهای قدیمی و قطع شدن کاربران واقعی را میگیرد. توجه کنید که ipset با ریبوت پاک میشود؛ اگر میخواهید بماند باید آن را ذخیره کنید و دقت داشته باشید که ست باید پیش از بازگردانی قوانین iptables ساخته شود، وگرنه بازگردانی با خطای «Set cannot be destroyed» شکست میخورد و ممکن است سرور بدون فایروال بالا بیاید:
ipset save > /etc/ipset.conf
درباره APF
در دستورالعملهای قدیمی، نصب فایروال APF و روشن کردن گزینه USE_AD = 1 در /etc/apf/conf.apf و افزودن آیپی به /etc/apf/deny_hosts.rules و سپس service apf restart توصیه میشد. این روش امروز منسوخ است: APF سالهاست بهطور فعال توسعه داده نمیشود و ماژول antidos آن هم همراهش. اگر روی سروری هنوز APF دارید، جایگزین درست همان CSF است که در بالا آمد؛ روی یک سرور هم نباید همزمان APF و CSF فعال باشند چون قوانین یکدیگر را خراب میکنند.
بلاک در سطح وبسرور
گاهی لازم است آیپی را فقط برای یک سایت ببندید، نه کل سرور. در Apache 2.4 (نسخهای که امروز روی تقریباً همه سرورها اجرا میشود) نحو صحیح این است:
<RequireAll>
Require all granted
Require not ip 218.92.207.28
</RequireAll>
نحو قدیمی Apache 2.2 که هنوز در بسیاری از آموزشها دیده میشود، شکل زیر بود. اگر با آن روبهرو شدید بدانید روی Apache 2.4 بدون ماژول mod_access_compat کار نمیکند و بهتر است به شکل بالا بازنویسی شود:
Order allow,deny Allow from all Deny from 218.92.207.28
اگر سایت پشت CDN یا پروکسی معکوس است، آیپیای که Apache میبیند آیپی پروکسی است نه بازدیدکننده؛ در این حالت بلاک بر اساس آیپی در وبسرور بیاثر (یا فاجعهبار) است، مگر اینکه ماژول mod_remoteip را درست تنظیم کرده باشید.
گام چهارم: mod_evasive روی Apache
ماژول mod_evasive (که قبلاً mod_dosevasive نام داشت) درخواستهای پرتکرار به یک صفحه یا یک سایت را میشمارد و آیپی پرتکرار را موقتاً بلاک میکند. دستورالعملهای قدیمی، کامپایل دستی نسخه 1.10.1 با apxs برای Apache 1.3 را توضیح میدادند؛ Apache 1.3 سالهاست پایان عمر شده و دیگر نیازی به کامپایل دستی نیست. از مخزن توزیع نصب کنید:
# AlmaLinux / Rocky / CentOS Stream (نیازمند مخزن EPEL) dnf install epel-release dnf install mod_evasive # Debian / Ubuntu apt install libapache2-mod-evasive a2enmod evasive
روی سرورهای cPanel در فعال کردن EPEL احتیاط کنید؛ این مخزن میتواند بستههای خود cPanel را با نسخههای ناسازگار جایگزین کند. اگر مجبورید از آن استفاده کنید، مخزن را غیرفعال نگه دارید و فقط با --enablerepo=epel برای همان یک بسته موقتاً روشنش کنید.
تنظیمات ماژول همان دایرکتیوهای قدیمی است و تغییری نکرده است؛ آنها را در فایل کانفیگ ماژول قرار دهید (روی AlmaLinux/Rocky در /etc/httpd/conf.d/mod_evasive.conf و روی Ubuntu در /etc/apache2/mods-available/evasive.conf):
DOSHashTableSize 3097 DOSPageCount 5 DOSSiteCount 50 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 DOSWhitelist 127.0.0.1
دو هشدار عملی: مقدار DOSPageCount 2 که در نوشتههای قدیمی توصیه میشد بهشدت سختگیرانه است و کاربران واقعی را هم بلاک میکند؛ با ۵ شروع کنید و در صورت نیاز پایین بیاورید. همچنین حتماً آیپی خودتان، آیپی سرویس مانیتورینگ و آیپی سرویسهای پرداخت را در DOSWhitelist بگذارید (این دایرکتیو برای هر آیپی یک بار تکرار میشود).
برای اعمال تنظیمات، وبسرور را ریاستارت کنید. دستور قدیمی /etc/init.d/httpd restart روی توزیعهای امروزی که از systemd استفاده میکنند جای خود را به اینها داده است:
# AlmaLinux / Rocky / CentOS systemctl restart httpd # Debian / Ubuntu systemctl restart apache2 # روی سرورهای cPanel /scripts/restartsrv_httpd
قبل از ریاستارت، صحت فایل کانفیگ را با apachectl configtest بررسی کنید؛ یک خطای تایپی در کانفیگ باعث میشود وبسرور بعد از ریاستارت اصلاً بالا نیاید.
گام پنجم: ModSecurity
ModSecurity یک فایروال لایه اپلیکیشن است و جلوی درخواستهای مخرب HTTP را میگیرد. توجه داشته باشید که این ابزار در برابر SYN Flood یا حملههای حجمی UDP کاری از دستش برنمیآید؛ حوزه کارش درخواستهای HTTP است.
مسیر قدیمی WHM » cPanel » Addon Modules مربوط به دوران EasyApache 3 است و دیگر وجود ندارد. روی cPanel امروزی (EasyApache 4):
- نصب ماژول:
WHM » Software » EasyApache 4و انتخاب بستهea-apache24-mod_security2(یا با دستورdnf install ea-apache24-mod_security2). - تنظیمات و روشن/خاموش کردن آن برای هر دامنه:
WHM » Security Center » ModSecurity™ Configuration. - فعال کردن مجموعه قوانین (مثلاً OWASP CRS):
WHM » Security Center » ModSecurity™ Vendors.
روی سرورهای بدون کنترلپنل، نام بسته به توزیع بستگی دارد: روی AlmaLinux/Rocky بسته mod_security از مخزن EPEL و روی Debian/Ubuntu بسته libapache2-mod-security2؛ مجموعه قوانین OWASP CRS هم جداگانه اضافه میشود. بعد از فعال کردن قوانین، اول چند روز آن را در حالت فقط ثبت لاگ (SecRuleEngine DetectionOnly) بگذارید و لاگها را بررسی کنید؛ قوانین سختگیرانه بهراحتی فرمها و پنل مدیریت سایت خودتان را هم بلاک میکنند.
گام ششم: تنظیم مقادیر Apache
مسیر فایل کانفیگ به توزیع و کنترلپنل بستگی دارد. مسیر قدیمی /usr/local/apache/conf/httpd.conf مربوط به EasyApache 3 است:
- cPanel با EasyApache 4:
/etc/apache2/conf/httpd.conf— این فایل بازتولید میشود و تغییرات دستیتان پاک میشود، پس آن را مستقیم ویرایش نکنید و ازWHM » Service Configuration » Apache Configuration » Global Configurationیا ازInclude Editorدر همان منو استفاده کنید. - AlmaLinux / Rocky / CentOS بدون کنترلپنل:
/etc/httpd/conf/httpd.conf - Debian / Ubuntu:
/etc/apache2/apache2.conf
حالا مهمترین تصحیح این بخش: توصیه قدیمی «KeepAliveTimeout را از ۳۰ به ۶۰ ببرید» درست نیست و در زمان حمله دقیقاً نتیجه معکوس میدهد. هر اتصال باز، یک worker از وبسرور را اشغال نگه میدارد؛ در حملههای اشباع اتصال، هرچه این عدد بزرگتر باشد سرور زودتر پر میشود. مقدار پیشفرض Apache 2.4 عدد ۵ است و زیر فشار باید همان یا کمتر بماند:
KeepAliveTimeout 5 MaxKeepAliveRequests 100 Timeout 30
درباره MaxKeepAliveRequests هم توصیه قدیمی «از ۱۰۰ به ۵۰ کم کنید» عملاً اثر محسوسی روی حمله ندارد؛ اهرم اصلی همان KeepAliveTimeout است. اگر سرور واقعاً زیر حمله اشباع اتصال است، مؤثرترین کار خاموش کردن موقت keep-alive با KeepAlive Off است. این کار را دائمی نکنید: در ترافیک عادی، تعداد هندشیکهای TCP و TLS و در نتیجه مصرف CPU را بالا میبرد؛ بعد از پایان حمله برش گردانید.
درباره تعداد پردازشها هم دو نکته نسخهای هست:
- دایرکتیو
MaxClientsدر Apache 2.4 بهMaxRequestWorkersتغییر نام داده است. نام قدیمی هنوز بهعنوان مترادف پذیرفته میشود ولی منسوخ است. MinSpareServersوMaxSpareServersفقط برای MPM prefork معنا دارند. اگر سرور شما با MPM event یا worker اجرا میشود (که روی نصبهای امروزی رایجتر است) معادلهای آنهاMinSpareThreadsوMaxSpareThreadsهستند.
برای اینکه بدانید کدام MPM فعال است:
httpd -V | grep -i mpm # AlmaLinux / Rocky / CentOS apache2ctl -V | grep -i mpm # Debian / Ubuntu
در تعیین MaxRequestWorkers زیادهروی نکنید. عدد بزرگ یعنی در زمان حمله سرور بهجای رد کردن درخواستها، حافظه را تمام میکند و به OOM میخورد. مقدار منطقی از تقسیم حافظه قابل تخصیص بر میانگین مصرف حافظه هر پردازش Apache به دست میآید.
اگر Nginx دارید
روی سرورهایی که Nginx جلوی وبسرور است، محدودسازی نرخ درخواست بومی و بسیار مؤثر است:
# در بخش http limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s; limit_conn_zone $binary_remote_addr zone=connperip:10m; # در بخش server limit_req zone=perip burst=20 nodelay; limit_conn connperip 20;
پیش از اعمال، با nginx -t کانفیگ را تست کنید و بعد systemctl reload nginx بزنید. اگر Nginx پشت CDN است، متغیر $binary_remote_addr آیپی CDN را میگیرد نه بازدیدکننده را؛ در آن حالت باید ماژول real_ip را تنظیم کنید وگرنه کل ترافیک سایت بهعنوان یک آیپی محدود میشود.
گام هفتم: سختسازی سطح کرنل در برابر SYN Flood
ماژول antidos فایروال APF کارش شمردن اتصالها و بلاک کردن آیپیهای پرتکرار بود (همان نقشی که امروز CT_LIMIT در CSF دارد)؛ اما لایهای که بهطور مشخص جلوی SYN Flood را میگیرد، خود کرنل است. یک فایل در /etc/sysctl.d/ بسازید (مثلاً 99-ddos.conf) و این مقادیر را در آن بگذارید:
net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.tcp_synack_retries = 2
سپس اعمالشان کنید:
sysctl --system
گزینه tcp_syncookies روی کرنلهای امروزی معمولاً از پیش روشن است؛ با sysctl net.ipv4.tcp_syncookies وضعیتش را ببینید. از کپی کردن فهرستهای بلندبالای «tuning» که در اینترنت پیدا میشوند خودداری کنید؛ بعضی از آن پارامترها (مثل tcp_tw_recycle) سالهاست از کرنل حذف شدهاند و بعضی دیگر پشت NAT ارتباط کاربران واقعی را قطع میکنند.
گام هشتم: اسکریپتهای جانبی مثل DDoS-Deflate
اسکریپت DDoS-Deflate سالها بهعنوان راهحل سریع معرفی میشد. نصب آن به این شکل بود:
wget http://www.inetbase.com/scripts/ddos/install.sh sh install.sh # و سپس افزودن این خط به crontab با دستور crontab -e */5 * * * * /usr/local/ddos/ddos.sh >/dev/null 2>&1
این آدرس دیگر در دسترس نیست و نسخه اصلی اسکریپت هم سالهاست نگهداری نمیشود؛ اجرای اسکریپتی که با wget از یک دامنه رهاشده گرفته شود، خودش یک ریسک امنیتی است و اصلاً این دستور را روی سرور واقعی اجرا نکنید — اینجا فقط برای این آورده شده که اگر در آموزشهای قدیمی دیدیدش بدانید چیست. کاری که این اسکریپت انجام میداد — شمردن اتصال هر آیپی و بلاک کردن آیپیهای بیش از حد — دقیقاً همان CT_LIMIT در CSF است که در گام دوم آمد. اگر CSF دارید، به این اسکریپت نیازی ندارید. اگر حتماً میخواهید از خود اسکریپت استفاده کنید، سراغ نسخههای فورکشدهای بروید که هنوز روی GitHub نگهداری میشوند و کد را پیش از اجرا بخوانید.
گام نهم: پیدا کردن و مهار سایت هدف
روی سرور اشتراکی معمولاً حمله به یک دامنه خاص است و بقیه سایتها قربانی جانبی میشوند. برای پیدا کردن آن دامنه، حجم لاگ دسترسی سایتها را مقایسه کنید (روی cPanel با EasyApache 4، لاگها معمولاً در /etc/apache2/logs/domlogs/ هستند):
ls -lS /etc/apache2/logs/domlogs/ | head -20
# پرتکرارترین آیپیها در لاگ یک دامنه (هم HTTP و هم HTTPS)
awk '{print $1}' /etc/apache2/logs/domlogs/example.com /etc/apache2/logs/domlogs/example.com-ssl_log | sort | uniq -c | sort -rn | head -20
# پرتکرارترین آدرسهای درخواستشده
awk '{print $7}' /etc/apache2/logs/domlogs/example.com /etc/apache2/logs/domlogs/example.com-ssl_log | sort | uniq -c | sort -rn | head -20
حتماً فایل -ssl_log را هم در بررسی بیاورید؛ امروز بیشتر ترافیک روی HTTPS است و اگر فقط فایل بدون پسوند را نگاه کنید، بخش اصلی حمله را اصلاً نمیبینید.
خروجی دستور آخر مهمترین سرنخ را میدهد: اگر همه درخواستها روی یک مسیر سنگین مثل صفحه جستجو یا xmlrpc.php و wp-login.php متمرکز است، پیش از هر کار دیگری همان مسیر را ببندید — این کار معمولاً بار سرور را بلافاصله پایین میآورد.
اگر یک سایت واقعاً کل منابع سرور را میبلعد و راهی برای فیلتر کردنش نیست، بهعنوان آخرین راه میتوانید حسابش را موقتاً معلق کنید تا بقیه سایتها بالا بمانند. در cPanel این کار از مسیر WHM » Account Functions » Suspend/Unsuspend an Account انجام میشود و مصرف پهنای باند هر حساب هم از WHM » Account Information » View Bandwidth Usage قابل مشاهده است. طبیعتاً پیش از انجام این کار به صاحب سایت اطلاع بدهید؛ تعلیق حساب سایت او را کامل از دسترس خارج میکند.
یک احتمال دیگر را هم فراموش نکنید: گاهی سرور «زیر حمله» نیست، بلکه یکی از سایتهایش هک شده و خودش دارد به بیرون حمله میکند یا اسپم میفرستد. اگر ترافیک خروجی غیرعادی است، مسئله امنیتی است نه DDoS.
جمعبندی: ترتیب کارها هنگام حمله
- با
ssتعداد و توزیع اتصالها را ببینید و مطمئن شوید مسئله واقعاً حمله است، نه یک اسکریپت یا کوئری خراب. - اگر حجم حمله از ظرفیت پورت شبکه بیشتر است، بلافاصله سراغ سرویسدهنده و راهکار بالادستی بروید؛ تنظیم سرور بیفایده است.
- پیش از دست زدن به فایروال، آیپی خودتان را در لیست سفید بگذارید و راه دسترسی جایگزین (کنسول/Rescue) را آماده داشته باشید.
- در CSF گزینههای
CT_LIMIT،CONNLIMITوPORTFLOODرا تنظیم کنید وcsf -rبزنید. - آیپیهای مشخصاً مهاجم را با
csf -dیاipsetببندید — نه با صدها قانون تکی iptables. - در سطح وبسرور،
KeepAliveTimeoutرا پایین نگه دارید،MaxRequestWorkersرا متناسب با حافظه تنظیم کنید و mod_evasive یاlimit_reqدر Nginx را فعال کنید. - مسیر یا دامنه هدف را از روی لاگها پیدا کنید و همان را محدود کنید.
- بعد از پایان حمله، بلاکهای موقت را بردارید و تنظیمهای اضطراری مثل
KeepAlive Offرا برگردانید تا کاربران واقعی قطع نمانند.