Optimal Fail2Ban Configuration: Combining Short Interval Checks with Long findtime for Comprehensive Brute Force Protection


4 views

Many administrators face this dilemma when configuring Fail2Ban: choosing between catching rapid brute force attempts (with short findtime) or catching slow, distributed attacks (with long findtime). Neither approach provides complete protection when used alone.

The solution lies in implementing multiple jail configurations with different time windows. Here's how to set this up in your jail.local file:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3

[sshd-fast]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
findtime = 600
maxretry = 3
bantime = 86400

[sshd-slow]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
findtime = 3600
maxretry = 5
bantime = 86400

The sshd-fast jail catches rapid attacks with a 10-minute window, while sshd-slow covers longer intervals. The different maxretry values prevent false positives - slower attacks require more attempts to trigger a ban.

To verify your setup, use these commands:

# Check active jails
sudo fail2ban-client status

# Monitor specific jail
sudo fail2ban-client status sshd-slow

# Test regex matching
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

For more precise detection, create custom filters in /etc/fail2ban/filter.d/:

[Definition]
failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* from <HOST>
            ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>
ignoreregex =

Remember to reload after changes:

sudo systemctl restart fail2ban

When hardening SSH security with Fail2Ban, we often face a dilemma between detection sensitivity and coverage duration. The default configuration requires choosing between:

# Option 1: Sensitive but short window
findtime = 600  # 10 minutes
maxretry = 2

# Option 2: Broad but potentially misses rapid attacks
findtime = 3600 # 1 hour
maxretry = 2

Instead of trying to make one jail do everything, implement multiple jails with different time windows:

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
bantime = 86400

[sshd-fast]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
findtime = 600
maxretry = 5
bantime = 86400

[sshd-slow]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
findtime = 3600
maxretry = 2
bantime = 86400

While Fail2Ban doesn't natively support separate scan intervals from findtime, we can achieve similar results through these methods:

Method 1: Aggressive Datepattern Matching

[sshd-aggressive]
findtime = 3600
maxretry = 3
datepattern = %%Y-%%m-%%d %%H:%%M:%%S
# Scan logs more frequently via systemd timer

Method 2: Combine with Logrotate Tweaks

# In /etc/logrotate.d/fail2ban
/var/log/fail2ban.log {
    rotate 4
    hourly
    missingok
    notifempty
    compress
    delaycompress
    postrotate
        fail2ban-client set logtarget /var/log/fail2ban.log
    endscript
}

For maximum control, implement a custom action that checks more frequently:

[Definition]
actionstart = 
actionstop = 
actioncheck = 
actionban = iptables -I fail2ban- 1 -s  -j DROP
actionunban = iptables -D fail2ban- -s  -j DROP

[Init]
# Custom scanning interval in seconds
scan_interval = 300

After implementation, verify with:

fail2ban-client status sshd
fail2ban-client get sshd findtime
tail -f /var/log/fail2ban.log

Monitor effectiveness by tracking patterns in your auth logs:

grep "Failed password" /var/log/auth.log | awk '{print $1,$2}' | uniq -c