fail2ban SSH Blocking Setup in 5 Minutes — Copy-Paste jail.local Example
Is Failed password flooding /var/log/auth.log every second? We'll skip the theory for now and start with a practical recipe you can copy-paste right away to auto-block SSH brute-force attacks. Follow the steps in order and you'll be done in 5 minutes.
1. Are You Under Attack Right Now? — 30-Second Diagnosis
Start by checking the scale. These three lines will show you where you stand.
# total failed login attempts
grep "Failed password" /var/log/auth.log | wc -l
# recent failed logins (check IPs and accounts)
lastb | head
# if the server is systemd-journal based
journalctl -u ssh | grep "Failed" | tail -n 20If wc -l returns hundreds or thousands, you're already a botnet scan target. Even in 2026, credential stuffing and automated scans against exposed port 22 keep growing. Time to put up a shield.
2. Install (by OS)
| Step | Ubuntu / Debian | CentOS / RHEL |
|---|---|---|
| Install | sudo apt update && sudo apt install -y fail2ban | sudo dnf install -y epel-release && sudo dnf install -y fail2ban |
| Start | sudo systemctl start fail2ban | sudo systemctl start fail2ban |
| Enable on boot | sudo systemctl enable fail2ban | sudo systemctl enable fail2ban |
| Verify | fail2ban-client version | fail2ban-client version |
It will run on the stock [DEFAULT] settings right after install, but we'll override them with the jail.local below so we get the values we actually want.
3. jail.local Copy-Paste Template
Create a new /etc/fail2ban/jail.local file and paste the following as-is. Never edit jail.conf directly — always override with jail.local.
[DEFAULT]
# Whitelist: never leave out your own IP (the #1 cause of self-ban incidents)
# 127.0.0.1/8 ::1 = local/IPv6 loopback; add your static IP and office range after that
ignoreip = 127.0.0.1/8 ::1 203.0.113.45 198.51.100.0/24
# How many failures before a ban
maxretry = 5
# Ban if maxretry is reached within this window (10 minutes)
findtime = 10m
# Ban duration (1 hour). Permanent ban is -1
bantime = 1h
# bantime = -1 ← replace with this line for a permanent ban
[sshd]
enabled = true
port = ssh
# --- log path / backend (pick one depending on OS) ---
# Ubuntu/Debian (classic file logs):
logpath = /var/log/auth.log
backend = auto
# For CentOS/RHEL or servers switched to systemd journal, use:
# backend = systemd
# (if you use backend = systemd, you can remove the logpath line)Here's what each parameter actually changes:
| Parameter | Example value | What it does |
|---|---|---|
maxretry | 5 | Ban after 5 failures within findtime |
findtime | 10m | Time window for counting failures |
bantime | 1h / -1 | Ban duration; -1 is permanent |
ignoreip | IP/CIDR | Whitelist that is never banned |
backend | auto/systemd | Whether to read logs from a file or from the journal |
Practical tip: As more servers expose SSH over IPv6, people often omit
::1fromignoreipand hit IPv6 loopback false positives. Include::1by default, as in the template above. When I spin up a new VPS, I drop this file in from the cloud web console before connecting over SSH — so if I lock myself out, I can still recover via the console.
4. Apply and Check Ban Status
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
# list all jails (sshd should appear if things are healthy)
sudo fail2ban-client status
# sshd jail details — who is banned right now
sudo fail2ban-client status sshd
# live-tail ban events
sudo tail -f /var/log/fail2ban.logA healthy fail2ban-client status sshd output looks like this.
Status for the jail: sshd
|- Filter
| |- Currently failed: 3
| |- Total failed: 1274
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 2
|- Total banned: 37
`- Banned IP list: 185.220.101.44 45.148.10.92Once IPs start showing up in Banned IP list, your defense is live.
5. Recovering from False Positives and "I Locked Myself Out" — Pre-Deploy Checklist
The most common incident is banning yourself. Stay calm and recover.
If you still have a live session, unban immediately:
sudo fail2ban-client set sshd unbanip 203.0.113.45If SSH is completely blocked (you're truly locked out):
- Connect via the cloud console's web VNC / serial console (AWS EC2 Serial Console, GCP / Naver Cloud web console, etc.)
- Unban immediately with
sudo fail2ban-client set sshd unbanip <YOUR_IP> - Add your IP and office range to
ignoreipinjail.local, thensudo systemctl restart fail2ban - Confirm you can SSH in normally again
Three safety checks to run before you deploy:
- ✅ Does
ignoreipinclude your static IP and127.0.0.1/8 ::1? - ✅ Did you avoid setting
bantimeto-1(permanent) from the start? (1his recommended initially) - ✅ Do you already have a console / recovery-mode access path?
Finally, fail2ban is only a temporary shield. Ultimately you should also enable key-based auth (disable password login) and change the SSH port, and if possible move to journal-based logs with backend = systemd.
References: Official Docs
The primary source for the behavior, settings, and errors covered in this post is the official documentation below. Check it for version-specific options and exact behavior.
FAQ
Q. After applying fail2ban, failed-login lines still keep piling up in auth.log. Is it broken?
A. That's expected. fail2ban reads the failure logs and only bans IPs that cross the threshold, so attempts before the ban still appear in the log. If Total banned in fail2ban-client status sshd is going up, it's working.
Q. Can I set bantime to permanent (-1)?
A. Yes. But run with 1h first, confirm you don't have false positives, then move to permanent. If you start with -1, a mistaken self-ban will not expire on its own.
Q. I'm on CentOS — what does "use systemd instead of logpath" mean?
A. Recent distros write logs to the systemd journal instead of a file. Set backend = systemd under [sshd] and fail2ban will read failure logs directly from the journal, with no separate logpath.
Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
Comments
Be the first to comment.