Fail2ban: protection against brute-force
SSH on any public VPS gets scanned by bots almost immediately — the authentication log quickly fills up with failed login attempts from strangers guessing passwords. Fail2ban watches these logs itself and temporarily bans an IP address in the firewall after a few failed attempts in a row. In this article you'll install fail2ban, configure the sshd jail in jail.local (bantime, findtime, maxretry), check its status with fail2ban-client status sshd, and learn how to manually unban an IP address.
What you'll need
- An mHost VPS on Ubuntu 22.04/24.04, Debian 11/12, or AlmaLinux/Rocky Linux 8/9.
- SSH access as
rootor a user withsudorights.
Step 1. Install fail2ban
Ubuntu / Debian
sudo apt update
sudo apt install -y fail2banThe fail2ban package is in the standard repository — no third-party source needed.
AlmaLinux / Rocky Linux
Fail2ban isn't in AlmaLinux/Rocky's standard repositories — enable EPEL first:
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-systemd fail2ban-firewalldEnable and check the service
sudo systemctl enable --now fail2ban
sudo systemctl status fail2banThe status should read active (running). While you're at it, check the client version:
fail2ban-client versionStep 2. Configure the sshd jail in jail.local
Create the file:
sudo nano /etc/fail2ban/jail.localAnd fill it in like this:
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
bantime = 1h
findtime = 10m
maxretry = 5What these parameters mean:
maxretry— how many failed login attempts a single IP is allowed;findtime— the time window they're counted over (if more thanfindtimepasses between attempts, that IP's counter starts over);bantime— how long an IP stays banned once it exceedsmaxretryattempts withinfindtime. Time can be written as a number of seconds or with a suffix:mfor minutes,hfor hours,dfor days,wfor weeks;ignoreip— a list of addresses fail2ban will never ban; injail.confthis option is commented out by default, so without it even localhost isn't exempt;enabled— thesshdjail is disabled by default injail.conf;enabled = trueturns it on here, injail.local.
Apply the changes:
sudo systemctl restart fail2banStep 3. Check the sshd jail status
List of active jails:
sudo fail2ban-client statusStatus
|- Number of jail: 1
`- Jail list: sshdDetails for a specific jail:
sudo fail2ban-client status sshdStatus for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 13
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 1
|- Total banned: 2
`- Banned IP list: 203.0.113.10Currently failed/Total failed— how many failed login attempts the filter sees right now (within the currentfindtime) and in total since the jail started;Currently banned/Total banned— how many IPs are banned right now and how many have been banned in total;Banned IP list— the specific banned addresses.
Step 4. Unban an IP address
If the wrong address ends up banned (say, your own, after a series of typos), remove the ban manually:
sudo fail2ban-client set sshd unbanip 203.0.113.10Check that the address is gone from the list:
sudo fail2ban-client status sshdBanned IP list should no longer contain that IP.
What's next
Fail2ban isn't limited to SSH — /etc/fail2ban/filter.d/ already ships ready-made filters for Nginx, Apache, Postfix, MySQL, and dozens of other services; to turn any of them on, add your own [jail-name] section to jail.local with enabled = true, the same way as [sshd] above. For IPs that keep coming back after being unbanned, fail2ban includes a separate recidive jail with a longer ban time — that's a topic of its own. Fail2ban bans IPs directly through the server's firewall (iptables/nftables/firewalld), so it works fine alongside ufw — if you haven't set up a firewall on the server yet, see "Setting up the UFW firewall".