اگر 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 را بگیری، ورود با رمز را غیرفعال کن و احراز هویت با کلید عمومی را اجباری کن.
دیدگاهها ۰
هنوز دیدگاهی ثبت نشده؛ اولین نفر باشید!