LinuxsecurityTested on real hardware

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
Shellbash
Updated
Script
bash
# 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 iptables after 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 iptables rules in real time — bans survive a fail2ban-client reload but are cleared on reboot unless dbpurgeage is set (bans are re-read from the database on restart by default)
  • backend = systemd reads 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