/보안/fail2ban SSH Blocking Setup in 5 Minutes — Copy-Paste jail.local Example
Securityfail2banSSH 보안

fail2ban SSH Blocking Setup in 5 Minutes — Copy-Paste jail.local Example

When SSH brute force floods auth.log, go from installing fail2ban to a copy-paste jail.local template in 5 minutes. Covers maxretry, bantime, and findtime settings plus false-positive unban recovery, laid out in command tables.

fail2ban SSH Blocking Setup in 5 Minutes — Copy-Paste jail.local Example

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.

Bash
# 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 20

If 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)

StepUbuntu / DebianCentOS / RHEL
Installsudo apt update && sudo apt install -y fail2bansudo dnf install -y epel-release && sudo dnf install -y fail2ban
Startsudo systemctl start fail2bansudo systemctl start fail2ban
Enable on bootsudo systemctl enable fail2bansudo systemctl enable fail2ban
Verifyfail2ban-client versionfail2ban-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.

INI
[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:

ParameterExample valueWhat it does
maxretry5Ban after 5 failures within findtime
findtime10mTime window for counting failures
bantime1h / -1Ban duration; -1 is permanent
ignoreipIP/CIDRWhitelist that is never banned
backendauto/systemdWhether to read logs from a file or from the journal

Practical tip: As more servers expose SSH over IPv6, people often omit ::1 from ignoreip and hit IPv6 loopback false positives. Include ::1 by 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

Bash
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.log

A healthy fail2ban-client status sshd output looks like this.

CODE
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.92

Once 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:

Bash
sudo fail2ban-client set sshd unbanip 203.0.113.45

If SSH is completely blocked (you're truly locked out):

  1. Connect via the cloud console's web VNC / serial console (AWS EC2 Serial Console, GCP / Naver Cloud web console, etc.)
  2. Unban immediately with sudo fail2ban-client set sshd unbanip <YOUR_IP>
  3. Add your IP and office range to ignoreip in jail.local, then sudo systemctl restart fail2ban
  4. Confirm you can SSH in normally again

Three safety checks to run before you deploy:

  • ✅ Does ignoreip include your static IP and 127.0.0.1/8 ::1?
  • ✅ Did you avoid setting bantime to -1 (permanent) from the start? (1h is 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.

확인 정보
✦ ✦ ✦
편집 검토 · Editorial Review

Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.

편집 책임 · Nodelog 기술 편집팀·발행 · ·업데이트 ·

Comments

Be the first to comment.