نصب Fail2ban در Ubuntu 24.04 برای امنیت SSH
آموزش نصب Fail2ban در Ubuntu 24.04 با دستور apt install و بررسی وضعیت sshd با fail2ban-client برای جلوگیری از حملات brute force و رفع مشکل Total failed 0.
عملکرد واقعی Fail2ban
Fail2ban یک دیمون (daemon) برای خواندن لاگها است. این برنامه پیامهای احراز هویت SSH را زیر نظر میگیرد و پس از تعداد مشخصی شکست در ورود از یک آدرس در یک بازه زمانی کوتاه، یک دستور فایروال را اجرا میکند که آن آدرس را برای مدتی مسدود میکند. کل ایده بر همین اساس است. تنظیمات آن در یک فایل شامل حدود 30 خط است و در Ubuntu 24.04، نصب آن تنها با یک دستور apt انجام میشود که پیش از هرگونه ویرایشی، سیستم را محافظت میکند.
درباره ماهیت آن دقیق باشید. Fail2ban هیچ کاربر را احراز هویت نمیکند، چیزی را رمزگذاری نمیکند و مانع از یک تلاش ورود مصمم نمیشود؛ این برنامه فقط مانع از تلاشهای مکرر از یک منبع واحد میشود. Fail2ban یک فیلتر نویز و محدودکننده نرخ (rate limiter) است، نه یک قفل. وظیفه آن این است که اسکنهای مداوم و پسزمینه روی پورت 22 را متوقف کند تا از منابع CPU، پهنای باند و فضای لاگ شما هدر نرود، و همچنین سرعت هر مهاجمی را که مجبور است در هر بار از یک آدرس استفاده کند، کاهش دهد.
آنچه Fail2ban جایگزین نمیکند
Fail2ban لایه سوم است، نه لایه اول. اگر سرور شما همچنان پذیرای passwordهای SSH باشد، یک botnet گسترده در هزاران آدرس میتواند به حدس زدن ادامه دهد؛ زیرا هر آدرس زیر آستانه ban شما باقی میماند و هرگز باعث فعال شدن آن نمیشود. دفاع واقعی در برابر این مسئله، authentication مبتنی بر key است که حدس زدن password را، فارغ از تعداد تلاشها، غیرممکن میکند. استفاده از Fail2ban در کنار key-only auth دو مزیت دارد: نویز حاصل از brute-force را از logهای شما حذف میکند و scannerها را زودتر اخراج میکند تا از حملات مداوم به port دست بکشند. با آن به عنوان defence in depth برخورد کنید. این ابزار پشتِ key authentication و پشت یک firewall قرار میگیرد، نه در مقابل آنها.
پیشنیازها و واقعیت Ubuntu 24.04
شما به یک VPS با سیستمعامل Ubuntu 24.04 نیاز دارید که دسترسی root یا sudo داشته باشد و SSH در آن فعال باشد — ترجیحاً با احراز هویت از طریق key. مصرف Fail2ban بسیار کم است: تنها چند ده مگابایت RAM نیاز دارد و نیازی به تنظیم محدودیتها نیست.
بخش زیر نکتهای است که در تمام راهنماهای قدیمی اشتباه شده است. سالها توصیه استاندارد این بود: "Fail2ban را نصب کنید، سپس backend = systemd را اضافه کنید، زیرا Ubuntu دیگر /var/log/auth.log را نمینویسد." این توصیه به یک تغییر واقعی اشاره دارد — ایمیجهای مدرن سرور و Cloud بدون rsyslog عرضه میشوند، بنابراین لاگهای SSH فقط در systemd journal نوشته میشوند و آن فایل متنی دیگر وجود ندارد — اما در Ubuntu 24.04، پکیج Fail2ban این موضوع را در نظر گرفته است. پکیج شامل /etc/fail2ban/jail.d/defaults-debian.conf است و این فایل، و نه تنظیمات پیشفرض اصلی، چیزی است که سرور شما واقعاً اجرا میکند:
[DEFAULT]
banaction = nftables
banaction_allports = nftables[type=allports]
backend = systemd
[sshd]
enabled = trueاین بخش را با دقت بخوانید، زیرا قبل از هر اقدامی، دو سوال را پاسخ میدهد. backend = systemd به این معناست که SSH jail لاگها را از journal میخواند، بنابراین نبودِ auth.log اهمیتی ندارد. banaction = nftables به این معناست که مسدودسازیها (bans) از طریق nftables اعمال میشوند، که فایروال واقعی در Ubuntu 24.04 است، نه iptables قدیمی. و [sshd] enabled = true به این معناست که jail از اولین بوت فعال است. نتیجه: یک نسخه پیشفرض از apt install fail2ban در Ubuntu 24.04، حملات SSH brute-force را بلافاصله مسدود میکند. بیشتر کار شما شامل تایید این موضوع، تنظیم سیاستها و اطمینان از عدم مسدود شدن خودتان است.
تله قدیمی auth.log هنوز در سه حالت باعث بروز مشکل میشود و شناخت آنها ضروری است: شما Fail2ban را با استفاده از pip به جای apt نصب کردهاید، بنابراین defaults-debian.conf وجود ندارد؛ شما داخل یک کانتینر بدون دسترسی (unprivileged container) هستید که systemd journal برای خواندن ندارد؛ یا از یک آموزش قدیمی پیروی کردهاید و backend = auto را در jail.local خود کپی کردهاید که تنظیمات پیشفرض و سالم را بازنویسی کرده است. بخش failure-modes دقیقاً نشان میدهد که هر کدام از این حالتها چگونه هستند.
Step 1: Install and confirm it is already banning
sudo apt update
sudo apt install -y fail2banنسخه Ubuntu 24.04 دارای Fail2ban 1.0.2 است و این بسته python3-systemd را به عنوان یک وابستگی اصلی (hard dependency) دریافت میکند، بنابراین backend مربوط به journal تمام موارد مورد نیاز را دارد. سرویس به صورت خودکار فعال و اجرا میشود:
sudo systemctl status fail2banشما به active (running) نیاز دارید. سپس زندانی (jail) را که در حال انجام وظیفه است بررسی کنید:
sudo fail2ban-client status sshdدر یک VPS عمومی که حتی برای چند دقیقه در دسترس بوده است، اغلب شاهد شمارش خطاها و مسدود شدن آدرسها خواهید بود؛ اینترنت به طور مداوم پورت 22 را اسکن میکند. این مدرکی است بر اینکه تنظیمات پیشفرض به درستی کار میکند. از این مرحله به بعد، شما در حال اصلاح تنظیمات هستید، نه ساختن آنها از صفر.
Step 2: Edit jail.local, never jail.conf
Fail2ban تنظیمات پیشفرض اصلی خود را در /etc/fail2ban/jail.conf نگه میدارد. آن فایل را ویرایش نکنید. هر apt upgrade از بسته نرمافزاری میتواند جایگزین آن شود و تغییرات شما بدون هیچ هشداری از بین میرود. Fail2ban فایلها را با یک ترتیب مشخص میخواند — ابتدا jail.conf، سپس تمام موارد در jail.d/، و در نهایت jail.local — و آخرین مقدار اعمال میشود. فایل .local متعلق به شماست و ارتقای بسته هرگز آن را تغییر نمیدهد. همین قاعده برای فیلترها نیز صدق میکند، جایی که یک فایل *.local جایگزین فایل اصلی filter.d/*.conf میشود.
بنابراین، شما یک jail.local کوچک مینویسید که فقط تنظیمات معدودی را که برایتان مهم است تغییر میدهد، و هر دو فایل jail.conf و jail.d/defaults-debian.conf بستهبندی شده را برای استفاده به عنوان مرجع، بدون تغییر باقی میگذارید.
Step 3: Write /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.localمحتوای زیر را در فایل قرار دهید و آدرس موجود در خط ignoreip را به IP عمومی خود تغییر دهید:
[DEFAULT]
# Ubuntu 24.04 already sets these two in jail.d/defaults-debian.conf.
# Pinning them here documents the dependency and survives if that
# file is ever removed or changed by an upgrade.
backend = systemd
banaction = nftables
# Ban for one hour ...
bantime = 1h
# ... if an address fails ...
maxretry = 5
# ... 5 times within 10 minutes.
findtime = 10m
# Never ban these. PUT YOUR OWN IP HERE.
ignoreip = 127.0.0.1/8 ::1 10.0.0.24
# Longer bans for repeat offenders: 1h, 2h, 4h ... up to a week.
bantime.increment = true
bantime.maxtime = 1w
[sshd]
enabled = trueهر خط کاربرد مشخصی دارد:
bantime،findtimeوmaxretryسیاستهای امنیتی هستند. مقدار پیشفرض ارائه شده درbantimeفقط 10 دقیقه است؛ اما 1 ساعت زمان منطقیتری است. اگر یک آدرس در مدت 10 دقیقه، 5 بار خطا داشته باشد، مسدود میشود. کاربران واقعی ممکن است یک یا دو بار رمز عبور را اشتباه تایپ کنند؛ اما 5 خطا در 10 دقیقه نشاندهنده یک script است.ignoreipمانند کمربند ایمنی عمل میکند. آدرس عمومی که با آن متصل میشوید را اینجا وارد کنید تا Fail2ban هرگز دسترسی شما را به سرور خودتان قطع نکند. اگر از یک اتصال خانگی با IP متغیر استفاده میکنید، این دلیلی برای استفاده از VPN در مراحل انتهایی است، نه دلیلی برای نادیده گرفتن این خط.bantime.increment = trueباعث میشود هر بار مسدود شدن، طولانیتر از بار قبلی باشد — ابتدا 1 ساعت، سپس 2 ساعت، سپس 4 ساعت — تا حداکثرbantime.maxtime. آدرسهایی که مدام بازمیگردند، به تدریج با مدتزمان بیشتری مسدود میشوند.
آدرس مورد نظر برای whitelist کردن را از سیستمی که با آن SSH میزنید پیدا کنید، نه از خود سرور:
curl -s ifconfig.meمیتوانید یک jail.local تنظیم شده بر اساس پورتها و سیاستهای مسدودسازی خود را از اینجا بسازید و سپس آن را در فایل کپی کنید:
Step 4: Restart and verify it is reading the journal
sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshdبخش -t ابتدا یک تست پیکربندی انجام میدهد؛ بنابراین اگر در jail.local غلط املایی داشته باشید، خطا در اینجا به وضوح نمایش داده میشود و سرویس بدون اطلاع از کار نمیافتد. وضعیت سالم jail به این صورت است:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 14
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 3
`- Banned IP list: 10.0.0.66عددی که ثابت میکند Fail2ban واقعاً در حال خواندن لاگهای ورود شماست، Total failed است. اگر این عدد بیشتر از 0 است، یا با تلاش مجدد برای ورود از یک دستگاه دیگر افزایش مییابد، یعنی journal در حال خوانده شدن است و کار شما تمام شده است. اگر با وجود دفعات متعدد تلاش ناموفق، این عدد روی 0 باقی ماند — و مطمئن هستید که از آدرس ignoreip تست نمیکنید — به بخش حالتهای خطا در ادامه مراجعه کنید.
دقت کنید که خط Journal matches همچنان نام sshd.service را ذکر میکند. در Ubuntu واحد SSH در واقع ssh.service است، اما فیلتر ارائه شده با _COMM=sshd نیز مطابقت دارد؛ همچنین OpenSSH در نسخه 24.04 خطاهای خود را از پردازشی به نام sshd ثبت میکند، بنابراین تطبیق برقرار است. این جزئیات تنها زمانی اهمیت دارد که از نسخه جدیدتر OpenSSH (نسخه 9.8 یا بالاتر، که در آن worker مربوط به هر اتصال، sshd-session است) استفاده کنید؛ حالتهای خطا این مورد را پوشش میدهند.
Step 5: Watch a real ban land, or force one to test
Real bans arrive on their own within minutes on any public VPS. To watch one, tail the log:
sudo tail -f /var/log/fail2ban.logA ban looks like this:
2026-07-15 10:31:40,502 fail2ban.filter [812]: INFO [sshd] Found 10.0.0.66 - 2026-07-15 10:31:40
2026-07-15 10:31:44,118 fail2ban.actions [812]: NOTICE [sshd] Ban 10.0.0.66To prove the machinery end to end without waiting, ban a documentation address by hand — never your own:
sudo fail2ban-client set sshd banip 10.0.0.66It prints 1, and the address appears under Banned IP list in fail2ban-client status sshd. Now confirm the block really exists in the firewall. On Ubuntu 24.04 that is nftables, not iptables:
sudo nft list table inet f2b-tableYou will see a set named addr-set-sshd holding 10.0.0.66, and a chain f2b-chain that rejects any source in that set. If fail2ban-client says an address is banned but nothing appears in nft list, your ban action does not match your firewall — see the nftables/iptables note in the failure modes.
Step 6: Unban yourself, and recover if you are locked out
اگر آدرسی را که نباید، یعنی آدرس خودتان را، Ban کردهاید: آن را حذف کنید:
sudo fail2ban-client set sshd unbanip 10.0.0.66در صورت موفقیت، دستور 1 بازگردانده میشود. برای پاکسازی تمام Banها در تمامی jailها:
sudo fail2ban-client unban --allبرای نجات خود به یک session SSH که از قبل باز است تکیه نکنید: nftables هر packet ارسالی از آدرس Ban شده به port 22 را رد میکند — حتی برای connectionهای established — بنابراین session موجود بلافاصله پس از اعمال Ban منجمد میشود. اگر خودتان را Ban کنید و هیچ entry از نوع ignoreip نداشته باشید، تا زمانی که مهلت Ban تمام نشود، از دسترسی خارج خواهید شد — برای بازیابی، از طریق کنسول وب ارائهدهنده خود (VNC یا serial) اقدام کنید، زیرا این کنسول از طریق SSH کار نمیکند؛ در آنجا یا منتظر پایان bantime بمانید و یا دستور unban را اجرا کنید.
Step 7: Make bans persist and escalate
Fail2ban بنهای فعال را در یک پایگاه داده کوچک SQLite در /var/lib/fail2ban/fail2ban.sqlite3 ذخیره میکند؛ بنابراین بنها پس از بازنشانی سرویس یا ریبوت شدن سیستم باقی میمانند و از دست نمیروند. خطوط bantime.increment که قبلاً اضافه کردهاید، هر بار تکرارکننده را به یک مشکل رو به رشد برای خود تبدیل میکند؛ به طوری که مدت زمان بن تقریباً از 1 ساعت به سمت 1 هفته دوبرابر میشود.
برای اعمال یک سیاست "سه بار تکرار" در سطح کل سیستم، Fail2ban یک jail به نام recidive ارائه میدهد که /var/log/fail2ban.log خود را زیر نظر دارد و به هر آدرسی که در تمام jailها به طور مکرر بن شده است، بنهای طولانی اعمال میکند. از آنجایی که [DEFAULT] شما اکنون از backend سیستمd استفاده میکند، این jail را مجدداً به فایل لاگ مورد نظر متصل کنید:
[recidive]
enabled = true
backend = auto
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5استفاده از backend = auto به همراه logpath صریح، باعث میشود recidive همچنان فایل plain fail2ban.log را بخواند؛ جایی که خطوط Ban که شمارش میشوند، در آنجا ظاهر میشوند. تنظیم پیشفرض systemd که به صورت سراسری اعمال کردهاید، آن را به journal ارجاع میدهد، در حالی که خطوط مورد نظر در آنجا نیستند.
Step 8: جفت کردن آن با SSH مبتنی بر کلید، و در حالت بهتر، یک VPN
Fail2ban تنها زمانی کارایی خود را ثابت میکند که در کنار احراز هویت مبتنی بر کلید (key authentication) استفاده شود. در یک فایل جایگزین در مسیر /etc/ssh/sshd_config.d/ — مثلاً /etc/ssh/sshd_config.d/00-hardening.conf — تنظیم کنید:
PasswordAuthentication no
KbdInteractiveAuthentication noسپس sudo systemctl restart ssh. با غیرفعال کردن رمز عبور، حملات brute force اصلاً نمیتوانند موفق شوند؛ در این حالت، هدف Fail2ban کاهش نویز در log و اخراج زودهنگام اسکنرها است. حالت امنتر این است که SSH را کاملاً از اینترنت عمومی جدا کنید: استفاده از یک WireGuard VPN خود-میزبان برای SSH و پورت 22 را در فایروال ببندید تا فقط از طریق تونل پاسخ دهد. هیچکس نمیتواند به پورتی که به آن دسترسی ندارد حمله brute-force انجام دهد؛ در این صورت Fail2ban به جای خط مقدم، به یک لایه حفاظتی پشتیبان تبدیل میشود.
Fail2ban فقط برای SSH نیست. هر سرویسی که ورودهای ناموفق را در log ثبت میکند، میتواند یک jail داشته باشد — مانند یک mail server، یک سایت nginx، یا مدیریت رمز عبور Vaultwarden خود-میزبان که ترجیح میدهید صفحه ورود وب آن برای حملات credential stuffing باز نماند. به محض اینکه یک وب اپلیکیشن پشت یک سایت nginx با گواهی Let's Encrypt قرار گرفت، یک فیلتر Fail2ban را به همان روشی که jail مربوط به SSH به journal اشاره میکند، به فایل access log آن متصل کنید.
Failure modes, with the exact strings you will see
"Have not found any log file for sshd jail", and Fail2ban will not start. This is the old auth.log problem, and on Ubuntu 24.04 you only hit it if something has overridden the packaged default — a pip install with no defaults-debian.conf, a container with no journal, or a stray backend = auto you pasted into jail.local. On a file backend with no /var/log/auth.log, the sshd jail cannot find its log and the whole daemon aborts. fail2ban.log shows:
ERROR Failed during configuration: Have not found any log file for sshd jailBecause that error is fatal, the service never comes up, and fail2ban-client status then reports the downstream symptom:
ERROR Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running?That "socket path" line does not mean Fail2ban is broken — it means it never started because one jail could not find its log. Setting backend = systemd in [DEFAULT], which the Ubuntu package already does for you, fixes both messages at once.
Jail is active but Total failed never moves. The daemon is running and the journal is being read, yet real failures pile up in journalctl -u ssh while the counter sits at 0. First rule out the obvious: you are testing from an address listed in ignoreip, so your own failures are exempt by design. If that is not it, you are on an OpenSSH build where the per-connection worker is sshd-session (9.8 and later), whose journal _COMM is sshd-session, not sshd, so the shipped match misses it. Widen the match in the [sshd] block:
[sshd]
enabled = true
backend = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd + _COMM=sshd-sessionRestart, fail a login on purpose from an address not in ignoreip, and confirm Total failed finally climbs.
You banned yourself: Connection refused. You left your own address out of ignoreip, tested a few bad logins, and now:
ssh: connect to host 10.0.0.10 port 22: Connection refusedThe refusal, rather than a silent timeout, is the nftables action's default reject verdict doing its job — on you. Fix it as in Step 6: unban from a session on a different, unbanned address, or from the provider console — a session already open from the banned address freezes too. Then add your address to ignoreip so it cannot happen again.
Fail2ban says an address is banned, but it can still connect. The counter in status sshd rises, yet the address still reaches port 22. This is a ban-action-versus-firewall mismatch, and on Ubuntu 24.04 it almost always means you overrode the working banaction = nftables with banaction = iptables-multiport copied from an older guide, on a box with no iptables layer. fail2ban.log shows:
fail2ban.actions [812]: ERROR Failed to execute ban jail 'sshd' action 'iptables-multiport'Delete that override and let the packaged nftables action stand, or, if you manage the firewall entirely through ufw and want bans to show up there, set banaction = ufw in [DEFAULT]. Restart and confirm the rule appears with sudo nft list ruleset | grep f2b.
Fail2ban will not start after editing jail.local. A typo — a stray heading or a bad time value — makes the service refuse to come up. Ask Fail2ban to check the config before it runs:
sudo fail2ban-client -tIt names the file and the jail with the problem, for example Errors in jail 'sshd'. Skipping..., so you fix the source rather than guessing.
FAQ
آیا نسخه پیشفرض Fail2ban در Ubuntu 24.04 واقعاً حملات SSH را مسدود میکند؟
بله. این بسته شامل /etc/fail2ban/jail.d/defaults-debian.conf است که jail مربوط به sshd را فعال میکند، backend = systemd را طوری تنظیم میکند که به جای /var/log/auth.log از systemd journal استفاده کند، و banaction = nftables را تنظیم میکند تا مسدودسازیها از طریق فایروال اصلی Ubuntu اعمال شوند. یک apt install fail2ban ساده از اولین بوت سیستم، از SSH محافظت میکند. با دستور sudo fail2ban-client status sshd وضعیت را تایید کنید و به دنبال مقدار غیر صفر در Total failed باشید.
چرا Fail2ban هیچ چیزی را در سرور من مسدود نمیکند؟
سه علت رایج را به ترتیب بررسی کنید. ممکن است در حال تست از آدرسی در ignoreip باشید که طبق طراحی از مسدودسازی مستثنی شده است. ممکن است با کپی کردن backend = auto در jail.local از یک راهنمای قدیمی، تنظیمات پیشفرض سالم را تغییر داده باشید؛ این کار قابلیت خواندن journal را در ایمیجی که فاقد auth.log است، از کار میاندازد. یا ممکن است داخل یک container باشید که اصلاً systemd journal برای خواندن ندارد. در fail2ban-client status sshd، مقدار Total failed را بررسی کنید: اگر در حالی که journalctl -u ssh شکستهای واقعی را نشان میدهد، این مقدار هرگز افزایش نمییابد، یعنی jail در حال خواندن منبع اشتباه است.
چگونه IP خود را از لیست مسدود شدهها خارج کنم؟
دستور sudo fail2ban-client set sshd unbanip YOUR.IP.HERE را اجرا کنید که در صورت موفقیت 1 را برمیگرداند، یا از sudo fail2ban-client unban --all برای پاک کردن تمام مسدودسازیها استفاده کنید. اگر دسترسی به SSH قطع شده است، از کنسول وب یا VNC ارائهدهنده خود برای اجرای همان دستور استفاده کنید؛ مسدودسازی، تمام بستهها (packets) از آدرس شما به پورت 22 را رد میکند، بنابراین حتی نشستهای (sessions) باز نیز متوقف میشوند. سپس آدرس خود را به ignoreip اضافه کنید تا این اتفاق تکرار نشود.
تفاوت jail.conf و jail.local در چیست؟
فایل jail.conf شامل تنظیمات پیشفرض اصلی Fail2ban است و با هر ارتقای بسته، بازنویسی میشود؛ بنابراین هر تغییری در آن در نهایت از بین میرود. بسته Debian/Ubuntu تنظیمات خود را از طریق jail.d/defaults-debian.conf روی تنظیمات قبلی اعمال میکند. تغییرات شما باید در jail.local اعمال شوند؛ این فایل آخرین فایلی است که خوانده میشود و بر هر دو فایل دیگر اولویت دارد و در هنگام ارتقا هرگز تغییر نمیکند. فایل jail.conf را فقط به عنوان یک مرجع برای مطالعه نگه دارید.
آیا Fail2ban جایگزین احراز هویت SSH مبتنی بر کلید (key-based) میشود؟
خیر. Fail2ban تعداد دفعات شکستهای مکرر از یک آدرس را محدود میکند؛ اما در برابر حملات حدس رمز (guessing) کند و توزیعشده که در آن هر آدرس زیر حد مجاز باقی میماند، اقدامی انجام نمیدهد. احراز هویت فقط با کلید (PasswordAuthentication no) حدس رمز را کاملاً غیرممکن میکند و در این حالت، Fail2ban فقط نویزهای لاگ را کاهش داده و اسکنرها را زودتر اخراج میکند. از هر دو استفاده کنید و در حالت ایدهآل، SSH را کاملاً از اینترنت عمومی جدا نگه دارید.