Block SSH brute-force with fail2ban (Linux)
Install fail2ban and configure an SSH jail that auto-bans IPs after repeated failed login attempts. Works on Ubuntu, Debian, Fedora, and openSUSE.
Distrosubuntu, debian, fedora, opensuse, centos, rocky
Shell
bashUpdated
Script
# Install fail2ban
# Ubuntu / Debian:
sudo apt-get install -y fail2ban
# Fedora / Rocky / AlmaLinux:
# sudo dnf install -y fail2ban
# openSUSE:
# sudo zypper install -y fail2ban
# Create jail.local — never edit jail.conf directly (it gets overwritten on updates)
sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[DEFAULT]
# Ban for 1 hour after 5 failures within 10 minutes
bantime = 3600
findtime = 600
maxretry = 5
# Use systemd journal as the log backend (works on all modern distros)
backend = systemd
# Email alerts (optional — set to your address or leave blank)
destemail =
sendername = fail2ban
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
maxretry = 3
EOF
# Enable and start
sudo systemctl enable --now fail2ban
# Verify the SSH jail is active
sudo fail2ban-client status sshd
What this does
Installs fail2ban and configures a jail for SSH that:
- Monitors
/var/log/auth.log(or the systemd journal on modern distros) for failed login attempts - Bans the offending IP via
iptablesafter 3 failures within 10 minutes - Keeps the ban in place for 1 hour
On internet-exposed servers, fail2ban typically reduces SSH log noise by 90%+ within hours.
Prerequisites
- A Linux distro with systemd (Ubuntu 20.04+, Debian 11+, Fedora 38+, openSUSE Leap 15+)
- Root or sudo access
- sshd running and accepting connections
Adjust ban settings
Edit /etc/fail2ban/jail.local to tune aggressiveness. For a server with only known users:
[DEFAULT]
bantime = 86400 # 24-hour ban
findtime = 300 # 5-minute window
maxretry = 3 # ban after 3 failures
[sshd]
enabled = true
maxretry = 2 # stricter for SSH specifically
Reload after any change:
sudo fail2ban-client reload
Whitelist your own IP
Add trusted IPs to ignoreip so you can never ban yourself:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
Separate multiple entries with spaces. CIDR ranges are supported.
If you changed the SSH port
Update the jail to match:
[sshd]
enabled = true
port = 2222
Useful management commands
# Show all active jails
sudo fail2ban-client status
# Show banned IPs for SSH
sudo fail2ban-client status sshd
# Manually unban an IP
sudo fail2ban-client set sshd unbanip 1.2.3.4
# Manually ban an IP
sudo fail2ban-client set sshd banip 1.2.3.4
# Test a regex pattern against a log line
sudo fail2ban-regex /var/log/auth.log sshd
Email alerts (optional)
To receive an email when an IP is banned, install sendmail and set destemail in jail.local:
[DEFAULT]
destemail = you@example.com
sendername = fail2ban
mta = sendmail
action = %(action_mwl)s
action_mwl sends the ban notification with the matching log lines included.
Notes
- fail2ban modifies
iptablesrules in real time — bans survive afail2ban-client reloadbut are cleared on reboot unlessdbpurgeageis set (bans are re-read from the database on restart by default) backend = systemdreads from the journal directly — no need for a log file on distros that don’t write to/var/log/auth.log- Pair this with the SSH hardening playbook (key-only auth) for layered defence