Any server with SSH exposed to the internet will see constant brute-force login attempts. fail2ban is a simple, effective way to deal with them.

Installation

apt update && apt install -y fail2ban

Configuration

Never edit /etc/fail2ban/jail.conf directly — it gets overwritten on updates. Create a local override:

cat > /etc/fail2ban/jail.local << EOF
[sshd]
enabled = true
port = 22
logpath = /var/log/auth.log
maxretry = 3
bantime = 7200
findtime = 600
EOF

This configuration:

  • Monitors SSH login attempts in auth.log
  • Bans an IP after 3 failed attempts within 10 minutes
  • Ban lasts 2 hours

Start the service:

systemctl enable fail2ban
systemctl start fail2ban

Monitoring

Check current jail status:

fail2ban-client status sshd

Sample output:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     847
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 3
   |- Total banned:     156
   `- Banned IP list:   203.0.113.42 198.51.100.7 192.0.2.15

Common Operations

# Unban a specific IP (when you accidentally lock yourself out)
fail2ban-client set sshd unbanip 203.0.113.42

# View fail2ban log
tail -50 /var/log/fail2ban.log

# Temporarily disable (emergency access)
systemctl stop fail2ban

Tuning Tips

  1. Don’t set maxretry too low: maxretry = 1 will likely ban you at some point when you mistype a password
  2. Reasonable bantime: 2 hours is usually enough to deter script kiddies without causing long lockouts
  3. Consider ignoreip: Add your static IP to prevent self-bans:
    ignoreip = 127.0.0.1/8 ::1 your.static.ip
    
  4. Check before banning yourself: If you’re changing SSH configs remotely, keep a second session open as a safety net

When fail2ban Isn’t Enough

For serious hardening, also consider:

  • Disabling password auth entirely (PasswordAuthentication no) and using key-based auth only
  • Moving SSH to a non-standard port (security through obscurity, but reduces log noise)
  • Using AllowUsers to restrict which accounts can SSH in

fail2ban is a good baseline defense, but it shouldn’t be your only layer.