How to set up fail2ban to stop brute-force attacks
fail2ban watches your logs and bans IPs that keep failing logins. Learn to install it, protect SSH, tune ban times, and add jails for web services.
Every public server sees a constant stream of automated login attempts โ bots trying username and password combinations against SSH. fail2ban stops them: it watches log files, and when an IP fails too many times, it temporarily bans that address at the firewall. Set it up once and the brute-force noise disappears.
How fail2ban works
fail2ban has two core ideas:
- Filters โ patterns that recognize a failed attempt in a log file.
- Jails โ rules that say "if this filter matches N times within this window, ban the IP for this long."
It ships with ready-made filters for SSH, Nginx, Apache, mail servers and more.
Step 1: Install
On Ubuntu or Debian:
sudo apt update
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
On a fresh install the SSH jail is active out of the box.
Step 2: Create a local config
Never edit the default jail.conf โ it gets overwritten on updates. Instead create jail.local, which overrides it:
sudo nano /etc/fail2ban/jail.local
A solid starting configuration:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 YOUR_HOME_IP
[sshd]
enabled = true
port = ssh
maxretry = 4
What these mean:
- bantime โ how long an IP is banned (here, one hour).
- findtime โ the window in which failures are counted.
- maxretry โ failures allowed before a ban.
- ignoreip โ never ban these addresses; add your own IP so you don't lock yourself out.
Step 3: Apply and check
Restart fail2ban to load your config:
sudo systemctl restart fail2ban
Check overall status and the SSH jail specifically:
sudo fail2ban-client status
sudo fail2ban-client status sshd
The SSH jail status lists currently banned IPs and totals. On a public server you'll see bans accumulate within hours.
Step 4: Escalate repeat offenders (optional)
To ban persistent attackers for much longer, increase bantime or enable "recidive" โ a meta-jail that bans IPs which keep getting banned. Add to jail.local:
[recidive]
enabled = true
bantime = 1w
findtime = 1d
maxretry = 5
Step 5: Protect web logins too
If you run Nginx, you can jail things like repeated 401/403s or bad bots. Enable the relevant jail in jail.local:
[nginx-http-auth]
enabled = true
fail2ban reads Nginx's error log to catch failed HTTP auth attempts. Similar jails exist for WordPress login abuse when paired with the right filter.
Managing bans manually
Unban an address (for example if you locked yourself out):
sudo fail2ban-client set sshd unbanip 203.0.113.5
Ban one manually:
sudo fail2ban-client set sshd banip 203.0.113.5
A note on keys
fail2ban is a great second layer, but the strongest SSH defense is key-only authentication โ with passwords disabled, brute-force attempts can't succeed at all. Use both: keys make attacks futile, fail2ban stops the attempts from cluttering your logs and consuming resources.
Locked out? Use the console
If you ever ban your own IP and can't SSH in, Nxeon's dashboard gives you out-of-band console access to the VPS, so you can log in directly and run the unban command above. Knowing that safety net exists makes tightening the rules stress-free.
With fail2ban running, your server quietly swats away the endless bot traffic, and your logs stay clean enough to spot anything that actually matters.