Fail2ban
fail2ban Cheat Sheet
Config: /etc/fail2ban/jail.local (jails) · /etc/fail2ban/fail2ban.local (daemon)
Backend: systemd journal (not log files) · Ban action: nftables
Jail: sshd · maxretry 4 · findtime 10m · bantime 1h
Bans trigger on auth failures, not connection counts.
Status & inspection
# Daemon alive?
sudo systemctl status fail2ban
sudo fail2ban-client ping # should answer "pong"
# Which jails are running?
sudo fail2ban-client status
# The sshd jail: current bans, totals, failure counts
sudo fail2ban-client status sshd
# Watch fail2ban's own log live
sudo journalctl -u fail2ban -f
# See the auth failures fail2ban is reading (same source it uses)
sudo journalctl -u ssh --since "1 hour ago" | grep -i fail
Bans: check / remove / add
# Is a specific IP banned? (listed under "Banned IP list")
sudo fail2ban-client status sshd
# UNBAN an address (the "I locked myself out" fix — run from IPMI console)
sudo fail2ban-client set sshd unbanip <ip>
# Unban everything in the jail
sudo fail2ban-client unban --all
# Manually ban an address
sudo fail2ban-client set sshd banip <ip>
The actual block lives in nftables — verify with:
sudo nft list ruleset | grep -A5 f2b
TRAVEL SCENARIO: I banned myself
Symptoms: SSH connects then drops instantly, or times out, from one specific location — while the VPN or another network works fine.
- Get in another way (UCI VPN, IPMI console, or another host).
sudo fail2ban-client status sshd→ confirm your IP is listed.sudo fail2ban-client set sshd unbanip <your-ip>- Fix whatever failed auth 4× in 10 min (wrong key? stale agent? password typos?). Otherwise you'll be banned again in minutes.
- Worst case, do nothing: bantime is 1 hour, then it clears itself.
Note: with the minimal ignoreip, your travel IPs are NOT exempt. Four bad auth attempts from the hotel wifi = 1-hour ban. Use keys, and check ssh -v output before retrying blindly.
Config changes
# Test config without applying
sudo fail2ban-client -t
# Reload after editing jail.local (keeps existing bans by default)
sudo fail2ban-client reload
# Full restart (re-reads everything; bans are restored from the
# persistent sqlite DB at /var/lib/fail2ban/fail2ban.sqlite3)
sudo systemctl restart fail2ban
Interaction with nftables
- Any
nft flush ruleset/systemctl reload nftableswipes the f2b ban sets. fail2ban still thinks they're banned. Fix:sudo systemctl restart fail2banafter firewall reloads. - Ban actions:
nftables-multiport(per-jail ports),nftables-allportsfor allports bans.
Current policy notes (jail.local)
ignoreip— keep minimal: loopback + witchetty's /32 (backup source). Anything listed here can brute-force sshd forever without a ban.- Consider
bantime.increment = truein[DEFAULT]for escalating bans on repeat offenders. allowipv6 = autolives in fail2ban.local[Definition], not jail.local (daemon setting, silences the startup warning).
Quick triage flowchart
Can't SSH in? ├─ Works from VPN but not current IP? │ ├─ IP not in $ssh_nets_v4 → nft issue (see nft sheet: temp rule) │ └─ IP in allowed range → probably banned → unbanip ├─ Works from nowhere? │ ├─ nftables ruleset empty/broken → nft sheet, IPMI console │ └─ sshd itself down → journalctl -u ssh -b └─ Connects but auth fails? → not a firewall problem; check keys/PAM