امنیت

راه‌اندازی Fail2ban برای مسدودسازی خودکار مهاجم

اگر لاگ SSH یا وردپرس پر از تلاش ناموفق است، این راهنما jail پیش‌فرض، نوشتن فیلتر سفارشی و جلوگیری از بلاک شدن خودت را قدم‌به‌قدم نشان می‌دهد.

امنیت

اگر journalctl -u ssh را باز کنی و ببینی در یک ساعت گذشته ۴۰۰۰ خط Failed password for root ثبت شده، مشکل دیگر «احتمالاً» نیست. سرورت روی اینترنت باز است و کسی دارد با دیکشنری رمزها را امتحان می‌کند. اولین کاری که اکثر مدیرها می‌کنند تغییر پورت SSH است؛ این کار فقط نویز اسکنرهای تنبل را کم می‌کند و جلوی اسکنر واقعی را نمی‌گیرد. کاری که واقعاً اثر دارد، بستن آدرس مهاجم بعد از چند تلاش ناموفق است. همان چیزی که Fail2ban انجام می‌دهد.

Fail2ban دقیقاً چه چیزی را می‌بندد و چه چیزی را نه

Fail2ban یک daemon پایتونی است که یک فایل لاگ را tail می‌کند، الگوهای regex را روی خطوط جدید اجرا می‌کند و وقتی تعداد تطبیق‌ها از یک آستانه در یک بازه زمانی رد شد، یک قاعده در فایروال سیستم می‌نویسد. روی Debian و Ubuntu این قاعده از طریق iptables یا nftables اعمال می‌شود؛ روی سیستم‌هایی با firewalld از firewall-cmd.

سه چیز را باید از اول بدانی. اول، Fail2ban جلوی حمله DDoS حجمی را نمی‌گیرد؛ اگر ترافیک در لایه شبکه باشد، بستن IP در سطح سرور بی‌فایده است و باید سراغ محافظت در برابر DDoS بروی. دوم، این ابزار جلوی ورود با کلید خصوصی دزدیده‌شده را نمی‌گیرد، چون آن ورود موفق است و در لاگ به‌عنوان خطا ثبت نمی‌شود. سوم، اگر پشت CDN یا پروکسی معکوس باشی، آدرس واقعی کاربر را نمی‌بینی و ممکن است IP خود CDN را بلاک کنی.

نصب و اولین jail روی SSH

روی Ubuntu 22.04 یا 24.04 نصب یک خط است:

apt install fail2ban -y
systemctl enable --now fail2ban

هرگز مستقیم داخل /etc/fail2ban/jail.conf ویرایش نکن. آن فایل با هر آپدیت بسته بازنویسی می‌شود و تنظیماتت بی‌صدا از بین می‌رود. یک فایل جدا بساز:

cat > /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 185.51.200.14

[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = systemd
EOF

مقدار maxretry = 5 یعنی پنج تلاش ناموفق در بازه findtime. عدد پیش‌فرض بسته ۵ است و برای اکثر سرورها منطقی. اگر آن را روی ۲ بگذاری، کاربری که رمز را دو بار اشتباه تایپ کند بیرون می‌ماند و تیکت پشتیبانی می‌گیری. اگر روی ۲۰ بگذاری، عملاً هیچ‌کس را نگرفته‌ای.

خط ignoreip را جدی بگیر. آدرس IP دفتر یا VPN خودت را همان اول آنجا بنویس، وگرنه اولین کسی که بلاک می‌شود خودتی. اگر دسترسی‌ات از طریق VPN سازمانی برای دسترسی امن کارکنان است، رنج آدرس آن VPN را هم اضافه کن.

بعد از ذخیره، اعتبارسنجی و ری‌استارت:

fail2ban-client -t
systemctl restart fail2ban
fail2ban-client status sshd

خروجی باید چیزی شبیه این باشد: Currently banned: 3 و Total banned: 47. اگر Currently banned صفر ماند و در journalctl -u fail2ban خط Failed to access socket path دیدی، یعنی سرویس بالا نیامده و باید لاگ را از اول بخوانی.

نوشتن فیلتر برای اپلیکیشنی که لاگش را کسی نمی‌خواند

jail پیش‌فرض فقط SSH را پوشش می‌دهد. اگر وردپرس داری، لاگ ورود ناموفق در /var/log/auth.log نیست؛ در دیتابیس یا لاگ افزونه امنیتی است. برای این حالت باید فیلتر سفارشی بنویسی.

فرض کن اپلیکیشنی داری که در /var/log/myapp/access.log خطی مثل این می‌نویسد:

2025-02-11 09:14:22 WARN login_failed ip=91.240.118.7 user=admin

فیلتر در /etc/fail2ban/filter.d/myapp.conf:

[Definition]
failregex = ^.*login_failed ip=<HOST>.*$
ignoreregex =

و jail متناظر در jail.local:

[myapp]
enabled  = true
filter   = myapp
logpath  = /var/log/myapp/access.log
maxretry = 8
bantime  = 24h

قبل از ری‌استارت، regex را جدا تست کن. این مرحله را ۹۰ درصد افراد رد می‌کنند و بعد می‌گویند «Fail2ban کار نمی‌کند»:

fail2ban-regex /var/log/myapp/access.log /etc/fail2ban/filter.d/myapp.conf

خروجی باید تعداد Lines matched بزرگ‌تر از صفر بدهد. اگر صفر داد، regex غلط است، نه سرور. نکته‌ای که خیلی‌ها را زمین می‌زند: <HOST> فقط IPv4 و IPv6 را می‌گیرد و اگر آدرس با پورت بیاید باید <HOST>:<PORT> بنویسی.

این‌جا اشتباه می‌کنند

رایج‌ترین اشتباهی که در تیکت‌ها می‌بینم این است: کسی bantime = -1 می‌گذارد تا «برای همیشه» بلاک شود، بعد سه هفته بعد متوجه می‌شود کاربران واقعی‌اش پشت یک NAT مشترک بوده‌اند و همه با یک IP بیرونی به سایت می‌آیند. یک نفر رمز را اشتباه می‌زند، کل شرکت بیرون می‌ماند. نشانه‌اش هم این است که ترافیک سایت نصف می‌شود ولی CPU و پهنای باند هیچ تغییری نکرده.

اشتباه دوم: بلاک کردن رنج IP موتور جستجو یا webhook سرویس پرداخت. اگر در ignoreip آدرس سرور پرداخت را نگذاری و آن سرور چند بار به یک endpoint محافظت‌شده درخواست ناموفق بزند، Fail2ban آن را می‌بندد و تراکنش‌ها بی‌صدا شکست می‌خورند. لاگ اپ را دست‌نخورده نگه دار تا بتوانی این را بعداً بازسازی کنی؛ درباره‌اش در لاگ ممیزی چیست و چگونه آن را دست‌نخورده نگه داریم؟ نوشته‌ام.

مقایسه گزینه‌های مسدودسازی

روشکجا اثر داردهزینه واقعی
Fail2banلایه سرور، روی سرویس‌های لاگ‌محورنیاز به نوشتن و تست regex برای هر اپ
تغییر پورت SSHفقط اسکنرهای تنبلهیچ محافظت واقعی؛ فقط نویز کمتر
کلید عمومی + غیرفعال‌کردن رمزریشه حمله را می‌بنددمدیریت کلید برای هر کاربر
فایروال ابریقبل از رسیدن ترافیک به سرورهزینه ماهانه و وابستگی به پنل

اگر فقط یک کار می‌توانی بکنی، ورود با رمز SSH را کامل غیرفعال کن و کلید عمومی بگذار. این کار ۹۵ درصد تلاش‌های brute-force را از ریشه بی‌اثر می‌کند و Fail2ban می‌شود لایه دوم. ترتیب درست همین است، نه برعکس. جزئیاتش در امنیت SSH؛ از تغییر پورت تا fail2ban و کلید عمومی آمده.

وقتی خودت را بلاک می‌کنی

این اتفاق برای همه می‌افتد. اگر دسترسی SSH‌ات قطع شد و مطمئنی IP خودت بلاک شده، از کنسول اضطراری سرور (KVM یا VNC پنل) وارد شو و اجرا کن:

fail2ban-client set sshd unbanip 185.51.200.14

برای دیدن لیست کامل:

fail2ban-client banned

یک نکته عملی: قبل از هر تغییر در jail.local، یک session SSH باز نگه دار و تغییر را در session دوم اعمال کن. اگر تنظیمات غلط باشد، session اول زنده می‌ماند و می‌توانی برگردانی. این عادت را برای هر تغییری در فایروال هم داشته باش.

اگر سرور پشت CDN است، باید X-Forwarded-For را در فیلتر بخوانی، وگرنه IP لبه CDN را بلاک می‌کنی و سایت برای همه از دسترس خارج می‌شود. برای بررسی اینکه آدرس واقعی کاربر چیست، از ابزارهای بررسی DNS و شبکه استفاده کن و هدرها را قبل و بعد از پروکسی مقایسه کن.

در نهایت، Fail2ban یک ابزار واکنشی است. اگر می‌خواهی بدانی سرورت همین حالا چه وضعیتی دارد، قبل از هر تغییری وضعیت سرویس را چک کن و بعد دست به کار شو. اگر ترجیح می‌دهی این لایه روی زیرساخت مدیریت‌شده اجرا شود، خدمات امنیت سرورنت این کار را پوشش می‌دهد.

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

آیا Fail2ban جلوی حمله DDoS را می‌گیرد؟

نه. Fail2ban بعد از رسیدن بسته به سرور و ثبت آن در لاگ واکنش نشان می‌دهد، پس برای حمله حجمی که پهنای باند را اشغال می‌کند دیر است. برای آن لایه باید از فیلتر لبه شبکه یا سرویس محافظت DDoS استفاده کنی.

چرا Fail2ban هیچ IP‌ای را بلاک نمی‌کند؟

در بیشتر موارد regex فیلتر با فرمت واقعی لاگ نمی‌خواند یا مسیر logpath اشتباه است. با fail2ban-regex روی همان فایل لاگ تست کن؛ اگر تعداد تطبیق صفر بود، مشکل در فیلتر است نه در سرویس.

بعد از بلاک شدن خودم چطور برمی‌گردم؟

از کنسول اضطراری سرور وارد شو و fail2ban-client set sshd unbanip <IP> را اجرا کن. برای جلوگیری از تکرار، آدرس IP ثابت خودت را در ignoreip فایل jail.local اضافه کن.

آیا باید پورت SSH را هم عوض کنم؟

تغییر پورت به‌تنهایی امنیت اضافه نمی‌کند و فقط حجم لاگ اسکنرهای ساده را کم می‌کند. اگر می‌خواهی واقعاً جلوی brute-force را بگیری، ورود با رمز را غیرفعال کن و احراز هویت با کلید عمومی را اجباری کن.

پشتیبانی سرورنت

تیم فنی و تحریریه‌ی سرورنت — تخصص در زیرساخت، شبکه و میزبانی وب.

خدمات امنیت
اشتراک‌گذاری:

دیدگاه‌ها ۰

هنوز دیدگاهی ثبت نشده؛ اولین نفر باشید!

دیدگاه خود را بنویسید

سرویس مرتبط

خدمات امنیت

تست نفوذ توسط متخصصان دارای مدرک OSCP، امن‌سازی زیرساخت و مانیتورینگ امنیتی ۲۴ ساعته — گزارش‌هایی که مدیر می‌فهمد و مهندس اجرا می‌کند.