News
🛡️ Security Tutorials Block SSH Brute-Force Attacks with fail2ban

Block SSH Brute-Force Attacks with fail2ban

Install fail2ban, understand how it works, and configure it to ban IPs that repeatedly fail SSH authentication — without locking yourself out.

Every server with a public IP gets hammered on port 22. Bots run continuously, cycling through common username and password combinations. fail2ban watches the auth log and bans source IPs after a configurable number of failures. It does not make your server impenetrable — key-based auth with passwords disabled does that — but it eliminates the background noise and reduces exposure from any accounts that still use passwords.


Install

sudo apt install fail2ban    # Debian / Ubuntu
sudo dnf install fail2ban    # RHEL / Fedora / Rocky

Enable and start:

sudo systemctl enable --now fail2ban

How it works

fail2ban reads log files and looks for patterns that indicate failed authentication. When a source IP triggers enough failures within a time window, fail2ban inserts a firewall rule that drops traffic from that IP for a configurable duration. After the ban expires, the rule is removed automatically.

For SSH, the default configuration watches /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL/Fedora) for failed login attempts.


Check the default SSH jail

fail2ban uses the concept of "jails" — each jail watches a specific service. The default installation includes an SSH jail.

sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 3
|  |- Total failed:     142
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 2
   |- Total banned:     18
   `- Banned IP list:   203.0.113.45 198.51.100.72

Currently banned shows IPs blocked right now. Total failed shows how much activity has been observed since fail2ban started.


Configure the SSH jail

fail2ban reads configuration from /etc/fail2ban/jail.conf. Never edit this file directly — it is overwritten on package updates. Create an override:

sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s

What each option does:

  • bantime — how long a banned IP stays blocked. 1h for most servers is reasonable. 24h or -1 (permanent) for anything facing serious attack traffic.
  • findtime — the window in which failures are counted. 5 failures in 10 minutes triggers a ban; 5 failures over two days does not.
  • maxretry — number of failures before a ban. 5 is the standard default. Lower it to 3 if you see heavy attack traffic.

Reload after changes:

sudo fail2ban-client reload

Whitelist your own IP

Before tightening fail2ban settings, whitelist any IP you access the server from. A misconfiguration that sets maxretry = 1 and you mistype your password once could lock you out.

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.10

ignoreip accepts IP addresses, CIDR ranges, and hostnames separated by spaces. Your home or office IP belongs here if it is static. For dynamic IPs, consider using ignoreself = true to at least protect the server's own loopback.


Manually ban and unban an IP

Ban an IP immediately:

sudo fail2ban-client set sshd banip 203.0.113.99

Unban an IP:

sudo fail2ban-client set sshd unbanip 203.0.113.99

The unban command is the one you need if you accidentally lock yourself out from a machine you have console access to. If you have no console access and you banned yourself, you need to go through your hosting provider's recovery console.


What fail2ban does not fix

fail2ban bans IPs after failures occur. It does not prevent the attempts — it responds to them. If an attacker is slow (one attempt per hour from many IPs), they stay under maxretry and never get banned.

The real protection against SSH brute force is key-based authentication with password login disabled. With PasswordAuthentication no in sshd_config, password attempts are rejected immediately and there is nothing for fail2ban to watch. See the SSH Key Authentication tutorial for the full setup.

Use fail2ban as a second layer, not the primary control.