Every server I deploy gets brute-force attempted within hours. SSH, HTTP auth, FTP, doesn't matter. The internet is full of bots scanning entire IP ranges 24/7 and they will find you.

Server room with network cables
Your server, minutes after being exposed to the internet

fail2ban is the lazy dev's answer to this. It reads your logs, spots repeated failures, and tells your firewall to drop the offender. No fancy IDS, no SIEM, just a simple Python script that watches log files and bans IPs.

Here is how I set it up on every server I run.

Install

sudo apt install fail2ban

That's it. On Debian/Ubuntu it ships with reasonable defaults. On RHEL/CentOS: sudo yum install fail2ban or sudo dnf install fail2ban.

How It Works

fail2ban has three concepts: filters, actions, and jails.

Firewall and network security
fail2ban acts as the gatekeeper between your logs and your firewall

A filter is a regex that matches a failure in a log file. An action is what happens when someone gets banned ( usually iptables drop ). A jail ties a filter to an action with parameters like how many retries before banning and how long the ban lasts.

The default install comes with a bunch of pre-made filters for common services. You can see them all in /etc/fail2ban/filter.d/.

The SSH Jail ( the only one you need to start with )

fail2ban ships with an SSH jail ready to go. You just enable it. Create a local override file ( never edit the main config directly, it gets overwritten on updates ):

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

Then find the [sshd] section and make sure it looks like this:

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime  = 3600
findtime = 600
Padlock on a door
Lock the door after the third failed knock

Here is what those params mean:

maxretry = 3: ban after 3 failed attempts

bantime = 3600: ban lasts 1 hour ( in seconds )

findtime = 600: count failures within a 10-minute window

If you want to be more aggressive ( and I usually am ), set bantime to 86400 for a 24-hour ban, or even -1 for a permanent ban.

Restart and Verify

sudo systemctl restart fail2ban
sudo fail2ban-client status

You should see something like:

Status
|- Number of jail:      1
`- Jail list:   sshd

Check the jail details:

sudo fail2ban-client status sshd

This shows you how many IPs are currently banned, the file list, and the filter in use. Give it a day and you'll see banned IPs pile up.

Adding More Jails

Most web servers get hammered on HTTP auth too. Here is a jail for nginx:

Code on screen
Every service exposed to the internet needs its own jail
[nginx-http-auth]
enabled = true
port    = http,https
filter  = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime  = 3600

The filter file /etc/fail2ban/filter.d/nginx-http-auth.conf already exists in the default install. Same idea for Apache, Postfix, Dovecot, and a bunch of others — just look in filter.d/ and enable the corresponding jail.

For custom applications, write your own filter. It's just a regex:

# /etc/fail2ban/filter.d/myapp.conf
[Definition]
failregex = ^%(__prefix_line)s.*Authentication failure.*from <HOST>
ignoreregex =

Then create a jail that uses it:

[myapp]
enabled = true
filter  = myapp
logpath = /var/log/myapp/auth.log
maxretry = 5
bantime  = 7200

Whitelist Your IP

Before you go banning everything in sight, whitelist yourself. In jail.local find the ignoreip line:

ignoreip = 127.0.0.1/8 ::1 YOUR_STATIC_IP

You really don't want to lock yourself out of your own server. Ask me how I know.

Checking Bans and Unbanning

List all banned IPs:

sudo fail2ban-client status sshd

Unban a specific IP ( maybe you locked yourself out ):

sudo fail2ban-client set sshd unbanip 1.2.3.4

Check the iptables rules fail2ban created:

sudo iptables -L f2b-sshd -v

fail2ban creates its own chain ( f2b-sshd, f2b-nginx-http-auth, etc. ) so it doesn't mess with your existing rules.

Ban Times That Scale

Matrix-style code rain
The bots never sleep, but with escalating bans they eventually give up

I like to make bans longer for repeat offenders. fail2ban supports this with bantime.increment:

[DEFAULT]
bantime.increment = true
bantime.factor   = 2
bantime.maxtime  = 604800

First ban: 1 hour. Second ban: 2 hours. Third: 4 hours. And so on, up to a week. Persistent bots get locked out for days while you sleep.

Conclusion

fail2ban is one of those install-and-forget tools that quietly does its job. Set it up once, whitelist your IP, and let it deal with the bots. It won't stop a determined attacker but it stops 99% of the automated noise that fills up your logs.

The source is on GitHub: https://github.com/fail2ban/fail2ban :)