How to Install and Configure Fail2Ban on Ubuntu: Stop Brute-Force Attacks in Their Tracks

So you’ve set up your self-hosted services — maybe a WordPress site, an SSH server, or a WireGuard VPN. You’re feeling good. But somewhere out there, bots are already hammering your server with thousands of login attempts per hour. If that thought makes you slightly uneasy, good — it should. This is where Fail2Ban comes in.

Fail2Ban is a lightweight intrusion-prevention tool that monitors your server’s logs for suspicious activity and automatically bans offending IP addresses using firewall rules. It’s free, open-source, and takes about 15 minutes to set up. Once it’s running, it quietly does its job in the background — like a very patient bouncer at the door of your server.

In this guide, I’ll walk you through installing Fail2Ban on Ubuntu, configuring it to protect SSH (the most common attack vector), and customizing it to protect other services. Let’s go.

What You’ll Need

  • A running Ubuntu server (20.04, 22.04, or 24.04 all work)
  • SSH access with sudo privileges
  • About 15 minutes

Step 1: Install Fail2Ban

First, update your package list and install Fail2Ban from Ubuntu’s repositories:

sudo apt update
sudo apt install fail2ban -y

Once installed, verify the service is running:

sudo systemctl status fail2ban

You should see active (running) in green. If it’s not running, start and enable it:

sudo systemctl enable --now fail2ban

Step 2: Create Your Local Configuration

Here’s a critical rule that trips up most newcomers: never edit /etc/fail2ban/jail.conf directly.

That file gets overwritten every time Fail2Ban is updated. Instead, you create a jail.local file that overrides the defaults without touching the original:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Find the [DEFAULT] section and update these key values:

[DEFAULT]
# Ban IPs for 10 minutes (600 seconds)
bantime  = 10m

# Look back over the last 10 minutes for failures
findtime = 10m

# Ban after 5 failed attempts
maxretry = 5

# Use ufw (Uncomplicated Firewall) — perfect for most Ubuntu setups
banaction = ufw

# Your email for notifications (optional but recommended)
# Change "root@localhost" to your real email
# Then set action = %(action_mwl)s below
destemail = root@localhost
sender   = [email protected]
action   = %(action_)s

A few notes on these values:

  • bantime: How long an IP stays banned. Start with 10 minutes. If you're seeing repeat offenders, bump this to 1h or even 24h.
  • findtime: The time window Fail2Ban checks for failures. If an IP accumulates maxretry failures within this window, it gets banned.
  • maxretry: The threshold. 5 is reasonable for SSH — it lets you fat-finger your password a few times without locking yourself out.

If you run ufw (Ubuntu's default firewall), set banaction = ufw. If you prefer raw iptables, you can leave it at the default iptables-multiport.

Step 3: Enable SSH Protection

Scroll down in jail.local to the [sshd] section and make sure it's enabled:

[sshd]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 5
bantime  = 10m

This tells Fail2Ban to watch /var/log/auth.log for failed SSH login attempts. When an IP hits 5 failures within 10 minutes, it gets banned for 10 minutes. Simple and effective.

If you've changed your SSH port from the default 22 (which I recommend), update the port line accordingly:

port = 2222

Step 4: Restart and Verify

Restart Fail2Ban to apply your changes:

sudo systemctl restart fail2ban

Now check that the SSH jail is active:

sudo fail2ban-client status sshd

You should see output like:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:

That means Fail2Ban is watching. Let's see if it's actually working.

Step 5: Test It (Optional but Fun)

From another machine (or another terminal session if you're feeling adventurous), deliberately fail SSH logins:

ssh wronguser@your-server-ip
# Enter wrong password 5+ times

Then check the jail status again:

sudo fail2ban-client status sshd

You'll see your test IP in the banned list. To unban it manually:

sudo fail2ban-client set sshd unbanip YOUR_IP

Step 6: Protect Other Services

Fail2Ban comes with filters for dozens of services. Here are two common ones for self-hosters:

Nginx (protect your web server)

Create a custom filter for nginx at /etc/fail2ban/filter.d/nginx-login.conf:

[Definition]
failregex = ^ .* "(GET|POST) .*" (401|403|404) .*

Then add a new jail section in your jail.local:

[nginx-login]
enabled  = true
port     = http,https
filter   = nginx-login
logpath  = /var/log/nginx/access.log
maxretry = 10
findtime = 60
bantime  = 3600

Protect Against Nginx Bot Abuse

For blocking bots that scan for common vulnerabilities:

[nginx-botsearch]
enabled  = true
port     = http,https
filter   = nginx-botsearch
logpath  = /var/log/nginx/access.log
maxretry = 2
bantime  = 86400

After adding new jails, restart Fail2Ban:

sudo systemctl restart fail2ban

Common Pitfalls

1. Locking yourself out

This is the #1 fear, and it's valid. Before enabling Fail2Ban on SSH, make sure you have console access (VPS providers like DigitalOcean, Linode, and Vultr offer a web console). You can also whitelist your home IP:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 YOUR_HOME_IP

Put your trusted IPs here and they'll never get banned, no matter how many failed attempts.

2. Editing jail.conf instead of jail.local

I mentioned this above, but it bears repeating: your changes will vanish on the next update. Always use jail.local.

3. Log file location mismatch

If you're running Ubuntu 24.04 with systemd-journald, authentication logs might be in the journal instead of /var/log/auth.log. Check with:

sudo journalctl -u sshd --no-pager | tail -20

If that's your log source, set backend = systemd in the [sshd] jail config.

4. UFW not enabled

If you set banaction = ufw but UFW isn't active, bans won't work. Check with:

sudo ufw status

If it's inactive, enable it (carefully — make sure your SSH port is allowed first!):

sudo ufw allow ssh
sudo ufw enable

Useful Commands Cheat Sheet

# Check overall status
sudo fail2ban-client status

# Check a specific jail
sudo fail2ban-client status sshd

# Unban an IP
sudo fail2ban-client set sshd unbanip 192.168.1.100

# Ban an IP manually
sudo fail2ban-client set sshd banip 192.168.1.100

# View Fail2Ban logs
sudo tail -f /var/log/fail2ban.log

What You've Accomplished

In about 15 minutes, you've turned your server from an open door into something with actual security. Fail2Ban will now:

  • Monitor your logs in real-time
  • Automatically ban IPs that brute-force your SSH
  • Protect your web services from bots and scanners
  • Free up resources that were being wasted on junk traffic

It's not a silver bullet — you should still use SSH keys instead of passwords, keep your software updated, and follow other security best practices. But Fail2Ban is one of the highest-impact, lowest-effort improvements you can make. It's the seatbelt of server security: simple, and it saves you when things go wrong.

Your future self, the one who's not debugging a compromise at 3 AM, will thank you.

Leave a Reply

Your email address will not be published. Required fields are marked *