How to Install and Configure fail2ban
fail2ban watches your logs and automatically bans IPs that fail to log in too many times. Here's how to install it and write custom jails.
Automated bots scan the whole internet, trying common usernames and passwords against every open SSH port. fail2ban is the standard answer: it tails your log files, spots repeated failures, and tells your firewall to drop the offending IP for a while. This guide installs it and sets up sensible jails.
Install fail2ban
On Ubuntu or Debian:
sudo apt update
sudo apt install fail2ban -y
The service starts automatically. Confirm it's running:
sudo systemctl status fail2ban
Never edit jail.conf directly
fail2ban ships /etc/fail2ban/jail.conf, which gets overwritten on upgrades. Your changes go in jail.local, which overrides it and survives updates:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Set sane defaults
Open /etc/fail2ban/jail.local and adjust the [DEFAULT] section:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1
That bans an IP for one hour after 5 failed attempts within 10 minutes. Add your own home/office IP to ignoreip so you never lock yourself out. For repeat offenders, enable escalating bans:
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1w
Enable the SSH jail
On modern Ubuntu, SSH logs go to the systemd journal, so use the systemd backend:
[sshd]
enabled = true
port = ssh
backend = systemd
maxretry = 3
If you moved SSH to a custom port, set port = 2222 to match. Restart to apply:
sudo systemctl restart fail2ban
{{SCREENSHOT}}
Check what fail2ban is doing
See overall status and per-jail detail:
sudo fail2ban-client status
sudo fail2ban-client status sshd
The per-jail output lists currently banned IPs and total failures. To manually unban an address:
sudo fail2ban-client set sshd unbanip 203.0.113.55
Protect a web server too
If you run Nginx, add jails for authentication failures and bad bots:
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
For a self-hosted WordPress site, pair this with the steps in secure a self-hosted WordPress site.
Write a custom jail
Say an app writes failed logins to /var/log/myapp.log in the form Failed login from <IP>. Create /etc/fail2ban/filter.d/myapp.conf:
[Definition]
failregex = Failed login from <HOST>
Then enable it in jail.local:
[myapp]
enabled = true
filter = myapp
logpath = /var/log/myapp.log
maxretry = 4
fail2ban is a layer, not the whole wall
fail2ban is reactive โ it bans after failures happen. Combine it with proactive measures: key-only SSH auth, a UFW firewall, and the broader strategy in protect a VPS from brute-force attacks.
The recidive jail: banning repeat offenders for longer
fail2ban ships a clever meta-jail called recidive that watches fail2ban's *own* log. When an IP is banned repeatedly across other jails, recidive bans it for a much longer period โ days or weeks. Enable it in jail.local:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5
This means an IP that keeps coming back after short bans eventually earns a week-long timeout, which sheds a lot of persistent noise.
Get notified when bans happen
By default fail2ban bans silently. If you want an email each time it acts, change the default action to one of the action_mw variants, which bans *and* mails a whois report:
[DEFAULT]
destemail = you@example.com
sender = fail2ban@yourserver
action = %(action_mw)s
You'll need a working local mail setup for this. For most single-server owners, periodically running sudo fail2ban-client status sshd is enough โ reserve email alerts for servers where you genuinely want a heads-up on attack volume.
Persisting bans across restarts
By default, restarting fail2ban clears active bans. If you'd rather bans survive a service restart or reboot, fail2ban's SQLite database (/var/lib/fail2ban/fail2ban.sqlite3) already tracks them โ ensure dbpurgeage in fail2ban.conf is long enough that recent bans aren't purged. This matters less than it sounds, because a genuinely malicious IP will simply re-trigger the jail within minutes of resuming its attack, and be banned again automatically.
FAQ
Does fail2ban work if I use SSH keys only?
Yes, though with password auth disabled there's far less to brute-force. It still usefully bans IPs probing for open ports and invalid users, keeping your logs clean.
Why isn't my SSH jail catching anything?
Usually the backend. On systemd-based Ubuntu, set backend = systemd; the old /var/log/auth.log path may not exist. Check sudo fail2ban-client status sshd.
Can I accidentally ban myself?
Yes. Add your IP to ignoreip, and remember most VPS hosts like Nxeon offer a web console to get back in if you do.
How long should bantime be?
Start at 1 hour with escalation for repeat offenders. Permanent bans can grow unwieldy and occasionally trap legitimate users on shared IPs.
Quick reference: the commands you'll use most
Once fail2ban is running, day-to-day management comes down to a handful of commands worth keeping handy:
- Overall status:
sudo fail2ban-client status - A specific jail (banned IPs, failures):
sudo fail2ban-client status sshd - Manually ban an IP:
sudo fail2ban-client set sshd banip 203.0.113.5 - Unban an IP:
sudo fail2ban-client set sshd unbanip 203.0.113.5 - Reload after config changes:
sudo fail2ban-client reload - Test your filter regex against a log:
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
That last one, fail2ban-regex, is invaluable when a jail isn't catching anything โ it shows exactly how many lines your filter matches, so you can debug a custom jail without waiting for real attacks. Put your settings in jail.local, add your own IP to ignoreip, and you'll rarely need to touch it again. It's also worth glancing at the ban activity every so often โ a sudden jump in banned IPs or failed attempts against a particular jail can be an early signal of a targeted campaign rather than the usual background scanning. fail2ban keeps a running tally in its status output and its own log, so that trend is always a single command away.
fail2ban is a low-effort, high-value addition to any server. For a VPS with full root access to configure it exactly how you like, see Nxeon VPS hosting and our security overview.