fail2ban
Installation
SKILL.md
Identity
- Unit:
fail2ban.service - Config:
/etc/fail2ban/jail.local(local overrides — never editjail.conf) - Jails dir:
/etc/fail2ban/jail.d/(drop-in jail files) - Filters dir:
/etc/fail2ban/filter.d/(regex patterns per service) - Actions dir:
/etc/fail2ban/action.d/(ban/unban actions) - Logs:
journalctl -u fail2ban,/var/log/fail2ban.log - Install:
apt install fail2ban/dnf install fail2ban
Key Operations
| Goal | Command |
|---|---|
| Check status (all jails) | sudo fail2ban-client status |
| Status of specific jail | sudo fail2ban-client status sshd |
| Unban an IP | sudo fail2ban-client set sshd unbanip 1.2.3.4 |
| Manually ban an IP | sudo fail2ban-client set sshd banip 1.2.3.4 |
| Test a filter | sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf |
| Reload config | sudo fail2ban-client reload |
| Reload specific jail | sudo fail2ban-client reload sshd |
| Show banned IPs for jail | sudo fail2ban-client get sshd banned |
| View recent bans | `sudo journalctl -u fail2ban |
Common Failures
| Symptom | Likely cause | Check/Fix |
|---|---|---|
| Jail not catching failures | Filter regex doesn't match log format | Test with fail2ban-regex; check datepattern |
| Ban not applied | Action misconfigured or iptables not working | Check fail2ban.log; verify action with fail2ban-client get sshd actions |
| IP unbanned immediately | ignoreip includes the IP |
Check ignoreip in jail.local |
| Service won't start | Syntax error in jail.local | fail2ban-client --test or check log for parse errors |
| Bans not persisting across restarts | dbpurgeage too short or DB issue |
Check /var/lib/fail2ban/fail2ban.sqlite3 |
| Legitimate users getting banned | findtime/maxretry too aggressive |
Raise maxretry or shorten bantime for affected jail |
Pain Points
- Never edit
jail.conf: It gets overwritten on upgrades. All customizations go injail.localorjail.d/*.conf. ignoreipis critical: Always add your own IPs/subnets toignoreip. A misconfigured jail can lock you out.- Log backend: fail2ban polls log files by default. For systemd-journald logs, set
backend = systemdin the jail. - Action backends: Default uses
iptables-multiport. On systems with nftables only, this may fail. Usenftablesaction explicitly. - Bantime multiplier:
bantime.multiplier = trueenables recidivism — repeat offenders get exponentially longer bans. Very useful. fail2ban-regexfor testing: Always test filters before deploying:sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/nginx-http-auth.conf- Database: Persistent ban state stored in
/var/lib/fail2ban/fail2ban.sqlite3. Survives restarts ifdbpurgeageis sufficient.
References
See references/ for:
jail.local.annotated— every jail.local directive with defaults and recommendationscustom-filters.md— writing custom filters for services not built-indocs.md— official documentation links
Related skills