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
- Don’t set maxretry too low:
maxretry = 1will likely ban you at some point when you mistype a password - Reasonable bantime: 2 hours is usually enough to deter script kiddies without causing long lockouts
- Consider ignoreip: Add your static IP to prevent self-bans:
ignoreip = 127.0.0.1/8 ::1 your.static.ip - 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
AllowUsersto restrict which accounts can SSH in
fail2ban is a good baseline defense, but it shouldn’t be your only layer.