Using Fail2Ban to block unauthorised login attempts
Introduction
Installing Fail2Ban
Configuring Fail2Ban
Introduction
Anyone having virtual machines exposed to the internet has been subject to third parties attempting to log in without authorisation. Opening port 22 to the internet for SSH access means that there will be attempts to log in to your machine with various accounts such as root and passwords.
There are a few ways to reduce this. Fail2Ban is a program that we can use to limit the number of logins via SSH by tracing the IP address and adding it to a temporary blacklist.
Installing Fail2Ban
On Debian systems we install the program:
sudo apt install fail2ban
For Fedora systems:
sudo dnf install fail2ban
To start and enable the corresponding systemd service:
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Configuring Fail2Ban
Let’s now edit the configuration file, it will use journald logs to get attempts to log into the machine via ssh:
sudo nano /etc/fail2ban/jail.local
We will now add a section for the configuring sshd service; it will use the ssh port, will filter by the sshd service in journalctl.
Below is a sample configuration file:
[sshd]
enabled = true
backend = systemd
port = ssh
filter = sshd
maxretry = 3
findtime = 600
bantime = 3600
ignoreip = 127.0.0.1/8
What these mean:
- backend = systemd → tells
Fail2Banto read from thesystemdjournal. - maxretry = 3 → ban after 3 failed attempts.
- findtime = 600 → failures must occur within 10 minutes.
- bantime = 3600 → ban lasts 1 hour.
- ignoreip = your-ip-address → this
IPaddress or subnet will not be added to the rule, so you do not lock yourself out of your machine for repeated unsuccessful login attempts.
Once we have finished editing the file, we will restart the service:
sudo systemctl restart fail2ban
We can check if it is working with the command:
sudo fail2ban-client status sshd
Below is a sample output:
Status for the jail: sshd
|- Filter
| |- Currently failed: 1
| |- Total failed: 5
| `- Journal matches: _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 2
`- Banned IP list: xx.yy.zz.tt
We can check the logs for ssh login attempts:
journalctl -u ssh -f
The results, no IP should appear more than maxretry value, which is 3 times, as it will be banned for bantime which is 1 hour:
Dec 13 13:24:23 wg-lon sshd-session[9486]: Connection closed by authenticating user root xx.yy.76.186 port 33004 [preauth]
Dec 13 13:24:37 wg-lon sshd-session[9488]: Connection closed by authenticating user root xx.yy.128.82 port 44978 [preauth]
Dec 13 13:25:03 wg-lon sshd-session[9490]: Connection closed by authenticating user root xx.yy.76.186 port 42414 [preauth]
To see the IP addresses that are banned or unbanned, use the command below:
sudo tail -f /var/log/fail2ban.log
It will display a log which is updated in real time with the tail -f command:
2025-12-13 16:29:24,714 fail2ban.filter [9525]: INFO [sshd] Found xx.xx.232.92 - 2025-12-13 16:29:24
2025-12-13 16:29:26,797 fail2ban.filter [9525]: INFO [sshd] Found xx.xx.232.92 - 2025-12-13 16:29:26
2025-12-13 16:29:29,047 fail2ban.filter [9525]: INFO [sshd] Found xx.xx.232.92 - 2025-12-13 16:29:28
2025-12-13 16:29:29,258 fail2ban.actions [9525]: NOTICE [sshd] Ban xx.xx.232.92
2025-12-13 16:48:28,231 fail2ban.actions [9525]: NOTICE [sshd] Unban xx.xx.231.179