Fail2ban لاگهای سرور را میخواند، آدرسهایی را که چند بار پشت سر هم ورود ناموفق دارند پیدا میکند و برای مدتی با قانون فایروال مسدودشان میکند. رایجترین استفادهاش جلوگیری از حدس رمز SSH است، ولی برای Nginx، Apache، میل سرور و پنلها هم کار میکند. نصبش ساده است: بسته را نصب کنید، فایل jail.local را بسازید، jail مربوط به sshd را روشن کنید و سرویس را ریاستارت کنید.
Fail2ban جای رمز قوی و ورود با کلید SSH را نمیگیرد. اگر ورود با رمز را بستهاید و فقط کلید قبول میشود، حدس رمز نتیجهای ندارد و Fail2ban فقط نویز لاگ را کم میکند. در سروری که ورود با رمز باز است، یا سرویسهایی دارد که با رمز وارد میشوند، Fail2ban یک لایه دفاعی مفید است. دیگر لایهها در چک لیست امنیت سرور لینوکس آمده است.
Fail2ban چطور کار میکند؟
سه مفهوم دارد. Filter الگوی خطهایی از لاگ است که ورود ناموفق را نشان میدهند. Jail ترکیب یک فیلتر، یک فایل لاگ و تنظیمهای مسدودسازی است. Action کاری است که با یک آدرس مشکوک انجام میشود، معمولاً اضافه کردن قانون به فایروال. سه پارامتر اصلی رفتار هر jail را مشخص میکنند:
| پارامتر | معنی |
|---|---|
maxretry | تعداد خطای مجاز پیش از مسدود شدن |
findtime | بازهای که خطاها در آن شمرده میشوند |
bantime | مدت مسدود ماندن آدرس |
مثلاً با maxretry برابر ۵ و findtime برابر ۱۰ دقیقه، آدرسی که در ۱۰ دقیقه ۵ بار اشتباه وارد شود، برای مدت bantime مسدود میشود.
مرحله اول: نصب
روی Ubuntu و Debian:
sudo apt update
sudo apt install fail2banروی AlmaLinux و Rocky اول مخزن EPEL لازم است:
sudo dnf install epel-release
sudo dnf install fail2banسرویس را فعال کنید تا بعد از ریاستارت سرور هم بالا بیاید:
sudo systemctl enable --now fail2banمرحله دوم: تنظیمات را در jail.local بنویسید
فایل /etc/fail2ban/jail.conf را ویرایش نکنید، چون با بهروزرسانی بسته بازنویسی میشود. تنظیمات خودتان را در /etc/fail2ban/jail.local بنویسید. این فایل روی مقدارهای jail.conf اولویت دارد. محتوای پیشنهادی برای شروع:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
[sshd]
enabled = trueمقدار ignoreip فهرست آدرسهایی است که هرگز مسدود نمیشوند. IP ثابت دفتر یا IP خودتان را اینجا بنویسید تا با چند بار اشتباه تایپ رمز، خودتان را از سرور بیرون نکنید. آدرس 203.0.113.10 در مثال فقط نمونه است.
روی Debian 12 و نسخههای جدیدتر، فایل /var/log/auth.log بهطور پیشفرض وجود ندارد، چون لاگها در journal هستند. اگر سرویس با پیام نبودن فایل لاگ بالا نمیآید، در بخش DEFAULT این خط را اضافه کنید:
backend = systemdبعد سرویس را ریاستارت کنید:
sudo systemctl restart fail2banمرحله سوم: بررسی وضعیت
sudo fail2ban-client status
sudo fail2ban-client status sshdدستور دوم تعداد خطاهای دیدهشده، تعداد آدرسهای مسدودشده و فهرست آنها را نشان میدهد. روی سروری که SSH آن به اینترنت باز است، بعد از چند ساعت معمولاً چند آدرس در فهرست میبینید؛ این طبیعی است و نشانه آلودگی سرور شما نیست.
آزاد کردن یک آدرس مسدودشده، مثلاً وقتی خودتان اشتباه قفل شدهاید:
sudo fail2ban-client set sshd unbanip 203.0.113.50اگر کاملاً بیرون ماندهاید، با کنسول سرور از پنل ارائهدهنده وارد شوید و همین دستور را بزنید.
مسدود کردن مهاجمان تکراری با recidive
آدرسی که بعد از پایان مسدودیت برمیگردد و دوباره تلاش میکند، با jail مخصوص recidive میتواند برای مدت بسیار طولانیتر مسدود شود. این jail لاگ خود Fail2ban را میخواند:
[recidive]
enabled = true
bantime = 1w
findtime = 1d
maxretry = 3یعنی آدرسی که در یک روز سه بار مسدود شده باشد، یک هفته مسدود میماند.
محافظت از Nginx و دیگر سرویسها
Fail2ban با فیلترهای آماده برای سرویسهای پرکاربرد همراه است. برای Nginx دو jail سرراست هست: nginx-http-auth برای ورود ناموفق با رمز پایه و nginx-botsearch برای درخواستهای پشت سر هم به آدرسهایی که وجود ندارند. هر کدام را فقط در صورتی روشن کنید که لاگ Nginx به مسیر پیشفرض مینویسد:
[nginx-http-auth]
enabled = true
[nginx-botsearch]
enabled = trueبرای میل سرور (Postfix و Dovecot)، پنلهای وب و سرویسهای دیگر هم jail آماده وجود دارد؛ فهرست آنها را در /etc/fail2ban/jail.conf میبینید. وردپرس فیلتر پیشفرض ندارد و برای محافظت از wp-login.php باید فیلتر مخصوص بنویسید یا از ابزار دیگری استفاده کنید. نصب و تنظیم Nginx در نصب Nginx روی اوبونتو آمده است.
هماهنگی با فایروال
Fail2ban برای مسدودسازی از ابزار فایروال سیستم استفاده میکند. روی Ubuntu با UFW، تنظیم زیر قانون را از طریق UFW اضافه میکند و در فهرست ufw status هم دیده میشود:
[DEFAULT]
banaction = ufwروی AlmaLinux و Rocky با firewalld، گزینه banaction = firewallcmd-rich-rules مناسب است. اگر مطمئن نیستید کدام action با سرور شما کار میکند، همان پیشفرض (iptables یا nftables) را نگه دارید و بعد از restart با sudo fail2ban-client status sshd ببینید مسدودسازی انجام میشود یا نه.
تست فیلتر با لاگ واقعی
پیش از اتکا به یک jail، ببینید فیلتر آن واقعاً خطهای لاگ شما را تشخیص میدهد:
sudo fail2ban-regex /var/log/auth.log sshdخروجی تعداد خطهای منطبق را میگوید. اگر صفر است و میدانید ورود ناموفق وجود داشته، مسیر لاگ یا فرمت آن با فیلتر نمیخواند.
خطاهای رایج
| نشانه | علت و راه حل |
|---|---|
| سرویس بالا نمیآید | sudo journalctl -u fail2ban را بخوانید؛ معمولاً خطای نگارشی در jail.local یا نبودن فایل لاگ است |
| مسدودسازی انجام نمیشود | jail فعال نیست، یا مسیر لاگ اشتباه است، یا backend درست انتخاب نشده |
| خودتان قفل شدهاید | IP را در ignoreip بنویسید و با کنسول سرور unban کنید |
| آدرس مسدود میشود ولی هنوز وصل میشود | action فایروال با فایروال فعال سرور نمیخواند |
| لاگ خیلی بزرگ میشود | bantime و maxretry را بازبینی کنید یا لاگها را با logrotate بچرخانید |
پس از تنظیم، وضعیت jailها را در بازبینی دورهای هم ببینید. فهرست کارهای هفتگی و ماهانه در چک لیست نگهداری سرور آمده است. و اگر مشکوک هستید سرورتان هک شده، نشانه های هک شدن سرور لینوکس را ببینید.
سوالات متداول
آیا Fail2ban جلوی حملات DDoS را میگیرد؟
نه. Fail2ban برای کند کردن حدس رمز و درخواستهای مشکوک از چند آدرس محدود مناسب است. حمله DDoS از هزاران آدرس میآید و نیاز به پاکسازی ترافیک در سطح شبکه یا سرویسهایی مثل Cloudflare دارد.
تغییر پورت SSH با Fail2ban چه رابطهای دارد؟
تغییر پورت تعداد تلاشهای ثبتشده در لاگ را کم میکند، ولی امنیت واقعی نمیآورد. اگر پورت SSH را عوض کردهاید، در jail هم همان پورت را با port = 2222 بنویسید.
Fail2ban روی سرور مجازی چقدر منابع میگیرد؟
بسیار کم؛ تقریباً فقط مصرف خواندن لاگها. روی سرور مجازی کوچک هم مشکلی ایجاد نمیکند.
فرق Fail2ban با CrowdSec چیست؟
هر دو لاگ را میخوانند و آدرسهای مشکوک را مسدود میکنند. CrowdSec علاوه بر قوانین محلی، فهرست مشترک مهاجمان جامعه کاربران را هم دریافت میکند. Fail2ban سادهتر است و فقط از لاگهای خود شما استفاده میکند.





