How to Install Fail2ban on Ubuntu 24.04

Fail2ban is an intrusion prevention software that protects servers from brute-force attacks. This guide covers installation, configuration, and practical examples for various services.

Prerequisites

  • Ubuntu 24.04 server
  • Root or sudo privileges
  • Basic understanding of Linux security concepts
  • Text editor (nano or vim)

Step 1: Update System

sudo apt update
sudo apt upgrade -y

Step 2: Install Fail2ban

sudo apt install fail2ban -y

Step 3: Create Initial Configuration

Create local configuration file:

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

Basic configuration with enhanced security:

[DEFAULT]
# Ban settings
bantime = 1h
bantime.increment = true
bantime.factor = 1
bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
findtime = 10m
maxretry = 5

# Email configuration
destemail = [email protected]
sender = [email protected]
action = %(action_mwl)s

# Whitelist trusted IPs
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16

# Logging settings
loglevel = INFO
logtarget = /var/log/fail2ban.log

Step 4: Configure Service-Specific Jails

SSH Protection (Enhanced)

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24h
findtime = 1h

[sshd-aggressive]
enabled = true
filter = sshd-aggressive
logpath = /var/log/auth.log
maxretry = 2
bantime = 48h
findtime = 30m

Web Server Protection

[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 3
bantime = 12h

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

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

FTP Server Protection

[vsftpd]
enabled = true
port = ftp,ftp-data,ftps,ftps-data
filter = vsftpd
logpath = /var/log/vsftpd.log
maxretry = 3
bantime = 6h

[proftpd]
enabled = true
port = ftp,ftp-data,ftps,ftps-data
filter = proftpd
logpath = /var/log/proftpd/proftpd.log
maxretry = 3
bantime = 6h

Step 5: Create Custom Filters

WordPress Login Protection

sudo nano /etc/fail2ban/filter.d/wordpress-auth.conf
[Definition]
failregex = ^%(__prefix_line)s.*Authentication failure for .* from 
            ^%(__prefix_line)s.*Failed login attempt for .* from 
ignoreregex =

Custom SSH Filter

sudo nano /etc/fail2ban/filter.d/sshd-aggressive.conf
[Definition]
failregex = ^.*Failed \S+ for .* from .*$
            ^.*ROOT LOGIN REFUSED.* from .*$
            ^.*[iI](?:llegal|nvalid) user .* from .*$
            ^.*User .* from  not allowed.*$
ignoreregex =

Step 6: Configure Email Notifications

sudo nano /etc/fail2ban/action.d/custom-email.conf
[Definition]
actionstart = echo -e "Fail2ban for jail  started" | mail -s "[Fail2ban]  started" %(__administratoremail__)s
actionstop = echo -e "Fail2ban for jail  stopped" | mail -s "[Fail2ban]  stopped" %(__administratoremail__)s
actionban = echo -e "IP: \nJail: \nTime: $(date)\nBan duration: %(bantime)s\nLog entries:\n$(grep '' /var/log/fail2ban.log)" | mail -s "[Fail2ban] Ban IP " %(__administratoremail__)s
actionunban = echo -e "IP: \nJail: \nTime: $(date)" | mail -s "[Fail2ban] Unban IP " %(__administratoremail__)s

Step 7: Create Monitoring Scripts

Daily Status Report

#!/bin/bash
# /usr/local/bin/fail2ban-report.sh

# Get all jails
JAILS=$(fail2ban-client status | grep "Jail list" | sed "s/ //g" | awk '{split($2,a,",");for(i in a) print a[i]}')

# Initialize report
REPORT="Fail2ban Daily Report\n========================\n\n"

# Check each jail
for JAIL in $JAILS
do
    REPORT+="Jail: $JAIL\n"
    REPORT+="$(fail2ban-client status $JAIL)\n\n"
done

# Add currently banned IPs
REPORT+="Currently Banned IPs\n-------------------\n"
for JAIL in $JAILS
do
    BANNED=$(fail2ban-client get $JAIL banned)
    if [ ! -z "$BANNED" ]; then
        REPORT+="$JAIL: $BANNED\n"
    fi
done

# Send report
echo -e "$REPORT" | mail -s "Fail2ban Daily Report" [email protected]

Step 8: Implement Advanced Features

Rate Limiting

[http-rate-limit]
enabled = true
filter = http-rate-limit
logpath = /var/log/nginx/access.log
findtime = 60
bantime = 3600
maxretry = 120

Custom Action for Persistent Offenders

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5

Step 9: Start and Enable Services

sudo systemctl start fail2ban
sudo systemctl enable fail2ban
sudo systemctl status fail2ban

Maintenance and Monitoring

Regular Status Checks

#!/bin/bash
# Check all jails status
fail2ban-client status

# View recent bans
tail -f /var/log/fail2ban.log | grep "Ban"

# Check specific jail status
fail2ban-client status sshd

Log Analysis

#!/bin/bash
# Top 10 banned IPs
grep "Ban" /var/log/fail2ban.log | awk '{print $NF}' | sort | uniq -c | sort -nr | head -10

# Failed attempts by service
grep "Failed" /var/log/fail2ban.log | awk '{print $5}' | sort | uniq -c | sort -nr

Troubleshooting

Common Issues and Solutions

  • Service won't start:
    sudo journalctl -xe
    sudo fail2ban-client -d
  • Configuration test:
    sudo fail2ban-client -t
  • Filter testing:
    sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

Best Practices

  • Regularly backup configuration files
  • Monitor log files for unusual patterns
  • Update whitelisted IPs as needed
  • Test new filters before deployment
  • Keep Fail2ban and system updated

Security Recommendations

  • Use incremental ban times
  • Implement custom filters for specific attacks
  • Monitor and adjust ban thresholds
  • Regular security audits
  • Keep comprehensive ban logs