Linux7 min read

Securing Linux with fail2ban

linuxfail2bansecurityintrusion-prevention

Fail2ban monitors log files for patterns indicating failed authentication attempts and bans offending IPs by updating firewall rules. It’s one of the easiest security improvements you can make on any Linux server.

Installation

sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Configuration

Don’t edit /etc/fail2ban/jail.conf directly. Create a local override:

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

Or better, create a file in /etc/fail2ban/jail.d/:

sudo nano /etc/fail2ban/jail.d/custom.conf

Protecting SSH

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
  • maxretry — number of failures before banning
  • findtime — the window for counting failures
  • bantime — how long the ban lasts (in seconds)

This bans an IP for 1 hour after 3 failed SSH attempts within 10 minutes.

For persistent bans, set bantime = -1. For incremental bans (each offense gets longer):

bantime = 10m
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w

Protecting other services

Fail2ban has filters for many services out of the box:

[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 3600

[postfix]
enabled = true
port = smtp,ssmtp
filter = postfix
logpath = /var/log/mail.log
maxretry = 5
bantime = 3600

Custom filters

Filters define what patterns to look for. They live in /etc/fail2ban/filter.d/.

Create a custom filter for your application:

sudo nano /etc/fail2ban/filter.d/myapp.conf
[Definition]
failregex = ^.*Failed login from <HOST>.*$
            ^.*Authentication error from <HOST>.*$
ignoreregex =

Test the filter against a log file:

sudo fail2ban-regex /var/log/myapp.log /etc/fail2ban/filter.d/myapp.conf

This shows matching lines and helps debug your regex.

Ban actions

The default action updates iptables. You can also:

Send email on ban:

action = %(action_mwl)s

This sends an email with the relevant log lines.

Custom actions:

action = %(action_)s
         sendmail-whois[name=sshd, dest=you@example.com]

Managing bans

Check status:

sudo fail2ban-client status
sudo fail2ban-client status sshd

Manually ban an IP:

sudo fail2ban-client set sshd banip 192.168.1.100

Manually unban:

sudo fail2ban-client set sshd unbanip 192.168.1.100

List banned IPs:

sudo fail2ban-client set sshd banip list

Recidive jail

Ban repeat offenders across all jails:

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 604800  ; 1 week
findtime = 86400  ; 1 day
maxretry = 3

If an IP gets banned 3 times in a day across any jail, it gets banned for a week.

Common mistakes

Editing jail.conf directly. Package updates overwrite it. Use jail.local or files in jail.d/.

Not checking log paths. The logpath must match where your service actually logs. Different distros put logs in different places.

Banning yourself. If your IP is dynamic or you connect from the same IP you’re protecting, add it to the ignore list:

[DEFAULT]
ignoreip = 127.0.0.1/8 your.trusted.ip

Too aggressive settings. Three retries in 10 minutes is reasonable for SSH. For web login forms, users mistype passwords — give them more chances.

Remarks

Fail2ban is set-it-and-forget-it security. Install it, configure SSH protection, and you’ve already dramatically reduced brute-force exposure. The custom filters let you protect any service that logs authentication failures. It’s not a firewall replacement — it’s a complement that reacts to patterns in your logs.

Related Posts