Set Up fail2ban on Ubuntu to Stop Brute Force
Install and configure fail2ban on Ubuntu 24.04 to auto-ban brute-force attackers: SSH jail, ban times, escalation, and whitelisting your own IP safely.
Any server with a public SSH port is hit by automated brute-force attacks within minutes of coming online โ bots cycle through common usernames and passwords around the clock. fail2ban is the classic defence: it watches log files, detects repeated authentication failures, and automatically bans the offending IP address by inserting a firewall rule. It turns a noisy, attacked service into a quiet one without any manual intervention.
This tutorial installs and configures fail2ban on Ubuntu 24.04 LTS: set up a local override config, enable an SSH jail with sensible ban times, whitelist your own IP so you never lock yourself out, and verify bans are actually happening. Every command is copy-pasteable.
Prerequisites
- Ubuntu 24.04 LTS server with
sudoaccess. - SSH already working โ ideally with key authentication. See our guide to SSH key auth and hardening.
- Your current public IP address, so you can whitelist it. Find it from your workstation with
curl ifconfig.me.
Step 1: Install fail2ban
Install the package from the Ubuntu repository and confirm the service is enabled:
sudo apt update
sudo apt install -y fail2ban
sudo systemctl enable --now fail2banOn Ubuntu 24.04, fail2ban uses systemd to read the journal by default, so it works with modern SSH logging out of the box. Check that it started:
systemctl status fail2banStep 2: Create a local configuration
Never edit jail.conf directly โ package updates overwrite it. Instead, create a jail.local file, which fail2ban reads last and which takes precedence:
sudo nano /etc/fail2ban/jail.localAdd the following baseline configuration. The [DEFAULT] section applies to every jail; [sshd] enables protection for SSH specifically:
[DEFAULT] # Whitelist: never ban these (localhost + your IP/range) ignoreip = 127.0.0.1/8 ::1 203.0.113.45Ban for 1 hour after 5 failures within 10 minutes
bantime = 1h findtime = 10m maxretry = 5
Use the systemd journal as the log source
backend = systemd
[sshd] enabled = true port = ssh
Replace 203.0.113.45 with your real public IP from the prerequisites. You can list several addresses or CIDR ranges separated by spaces.
Step 3: Consider escalating repeat offenders
To punish persistent attackers more harshly, enable incremental banning so each repeat ban lasts longer. Add this to the [DEFAULT] section:
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1wWith these settings, a repeat offenderโs ban time doubles on each new ban, capped at one week โ a strong deterrent against bots that keep returning.
Step 4: Apply the configuration
Restart fail2ban so it reads jail.local, then confirm there were no syntax errors:
sudo systemctl restart fail2ban
sudo systemctl status fail2banIf the service fails to start, your config has a typo; check the journal:
journalctl -u fail2ban --since '5 min ago'Step 5: Verify the jail is active
fail2ban ships with a control client, fail2ban-client. List active jails and inspect the SSH jail:
sudo fail2ban-client status
sudo fail2ban-client status sshdThe sshd status shows currently failed and banned IP counts plus the journal it is watching:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 12
| - Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd - Actions
|- Currently banned: 1
|- Total banned: 3
`- Banned IP list: 198.51.100.22Step 6: Test and manage bans
You can ban and unban addresses by hand to confirm the firewall integration works. Unban a legitimate IP that got caught:
sudo fail2ban-client set sshd unbanip 198.51.100.22To test from the firewall side, inspect the rules fail2ban inserts (it uses nftables on Ubuntu 24.04):
sudo nft list ruleset | grep -A5 f2bBanned addresses appear in a dedicated fail2ban set, and connection attempts from them are dropped before SSH ever sees them.
Protecting other services
fail2ban is not limited to SSH. If you run a web server, you can add jails for Nginx authentication failures or bad bots. For example, to ban repeated HTTP auth failures, add to jail.local:
[nginx-http-auth]
enabled = true
port = http,httpsThis pairs well with a properly configured Nginx reverse proxy fronting your apps.
Troubleshooting and common pitfalls
- Jail shows 0 banned despite attacks โ the
backendis wrong. On Ubuntu 24.04 usebackend = systemdso fail2ban reads the journal rather than a missing/var/log/auth.log. - You banned yourself โ access the server via its console and run
fail2ban-client set sshd unbanip YOUR_IP, then add your IP toignoreip. - Service will not start โ a syntax error in
jail.local; checkjournalctl -u fail2ban. - Bans expire too fast or too slow โ tune
bantime,findtime, andmaxretryto your threat model.
Where this fits in a hardened baseline
fail2ban is one layer of defence in depth. Combine it with a host firewall โ see setting up UFW โ and with key-only SSH from the hardening guide above. Together these form the security baseline expected of any internet-facing server.
Conclusion
You installed fail2ban, configured an SSH jail with sensible ban times and escalation, whitelisted your own IP, and verified that attackers are being banned at the firewall. This kind of layered hardening is exactly the standard clouditiv applies across its platform: a sovereign, ISOย 27001 / BSIย C5-certified private cloud on Ubuntu 24.04 + OpenStack 2025.2, with intrusion defence baked in and data kept in Germany. Learn more about our digital sovereignty solution.