Module 5 · 5.3
English
fail2ban against guessing attempts
Module 5: Shielding the network · Reading time: 10 minutes
Learning objective: After this lesson you can set up fail2ban for SSH, read its status and log, unban an address, and explain what fail2ban does and does not protect.
Key concepts: brute force, jail, filter, action (banaction), maxretry, findtime, bantime, bantime.increment, ignoreip, backend systemd, jail.conf, jail.local and jail.d, fail2ban-client, recidive
The door-handle rattlers of the internet
Look at the SSH log one day after installation and you will see it: hundreds of login attempts, with names such as root, admin, test, ubuntu and oracle, from addresses all over the world.
anna@web1:~$ sudo journalctl -u ssh --since today | grep -c "Invalid user"
412
anna@web1:~$ sudo journalctl -u ssh --since today | grep "Invalid user" | tail -n 3
nov 09 14:02:11 web1 sshd-session[20311]: Invalid user admin from 203.0.113.77 port 51522
nov 09 14:02:13 web1 sshd-session[20313]: Invalid user oracle from 203.0.113.77 port 51544
nov 09 14:02:16 web1 sshd-session[20315]: Invalid user test from 203.0.113.77 port 51560(On Ubuntu the service is called ssh, on AlmaLinux and Rocky sshd. The process name can be sshd or sshd-session, depending on the OpenSSH version.) This is a brute-force attack: bots simply trying every common name and password. If you log in with keys and have password login switched off (lesson 2.2), they will never get in, however often they try. But they fill up your log, cost some computing power, and on services that do require a password (webmail, an admin panel) they can be genuinely dangerous.
fail2ban reads logs, recognises failed attempts, and locks an address that fails too often out of the firewall for a while.
How fail2ban thinks: jails
fail2ban works with jails. A jail combines three things:
- a filter: regular expressions that recognise failed attempts in a log (for example the line "Invalid user ... from <adres>");
- an action: what happens after too many attempts, usually a firewall rule that blocks the address (
banaction, on Debian 13 via nftables by default); - thresholds: how many failed attempts (
maxretry) within what time (findtime) lead to a ban of how long (bantime).
The default values from jail.conf are: maxretry = 5, findtime = 10m, bantime = 10m. So: five failed attempts within ten minutes results in a ten-minute ban.
Installing, and the Debian 12 pitfall
anna@web1:~$ sudo apt install fail2ban
anna@web1:~$ sudo systemctl status fail2banOn Debian and Ubuntu the jail for SSH ([sshd]) is already switched on after installation, through the file /etc/fail2ban/jail.d/defaults-debian.conf.
There is one well-known pitfall. fail2ban needs to know where the log is. That used to be the text file /var/log/auth.log. Since Debian 12, rsyslog is no longer installed by default and the messages are only in the systemd journal (lesson 6.2). The Debian 12 fail2ban package still looked for /var/log/auth.log, could not find it and did not start. Debian 13 fixed this by setting backend = systemd for SSH in defaults-debian.conf. On Debian 12 you fix it yourself (see below) by doing the same. Ubuntu still has rsyslog by default, but backend = systemd works there too.
Your own settings: jail.local
Never edit jail.conf: that file is replaced during an update. Put your own settings in /etc/fail2ban/jail.local or in a file in /etc/fail2ban/jail.d/ with the extension .local:
# /etc/fail2ban/jail.d/eigen.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
bantime.increment = true
ignoreip = 127.0.0.1/8 ::1 198.51.100.20
[sshd]
enabled = true
backend = systemdWhat the lines do:
bantime = 1h: a one-hour ban instead of ten minutes.bantime.increment = true: anyone who comes back after a ban gets a longer ban each time.ignoreip: addresses that are never banned. Put your office's fixed IP address here, if you have one. Do not add large ranges here "just to be safe".backend = systemd: read the journal instead of a text file (required on Debian 12, recommended everywhere). This needs the packagepython3-systemdto be installed; it usually already is, as a dependency.
Reload and check:
anna@web1:~$ sudo fail2ban-client -t # test the config
OK: configuration test is successful
anna@web1:~$ sudo systemctl reload fail2ban
anna@web1:~$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshdReading the status, banning and unbanning
anna@web1:~$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 3
| |- Total failed: 1288
| `- Journal matches: _SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
|- Currently banned: 2
|- Total banned: 117
`- Banned IP list: 203.0.113.77 198.51.100.140"Currently failed" are addresses that have made attempts but are not yet over the threshold. "Currently banned" are the addresses that are blocked right now.
Have you locked yourself out (for example by trying a few times with the wrong key or username)? Then log in from another network or via the console and unban your address:
anna@web1:~$ sudo fail2ban-client set sshd unbanip 198.51.100.20fail2ban's own log is in /var/log/fail2ban.log and shows when each address was banned and unbanned:
2026-11-09 14:02:16,903 fail2ban.actions [811]: NOTICE [sshd] Ban 203.0.113.77
2026-11-09 15:02:17,120 fail2ban.actions [811]: NOTICE [sshd] Unban 203.0.113.77Repeat offenders: recidive
Some bots simply come back after every ban. There are two tools for this. bantime.increment (above) makes the ban longer each time. On top of that there is the recidive jail: it reads fail2ban's own log and bans an address that has been banned often within a day for a week, on all ports. Switch it on in your .local file:
[recidive]
enabled = trueWhat fail2ban does and does not do
fail2ban is useful, but it is not the lock on the door. The lock is logging in with a key, with passwords switched off (lesson 2.2). So also know what fail2ban cannot do:
- A distributed attack from thousands of addresses, each making one or two attempts, never goes over
maxretry. - A weak password stays weak. fail2ban slows down the guessing, nothing more.
- Only what is in a log: a service that does not log failed attempts, or a log that fail2ban does not read, goes unseen.
- Docker: bans in the normal firewall chain do not apply to published container ports (lesson 9.3). Services in containers need a separate setting (an action on the
DOCKER-USERchain).
What fail2ban does do well: keep your log quiet, reduce the load from bots, and protect services where you (still) use passwords, such as webmail or an admin panel. For services like these there are filters for nginx, Postfix, Dovecot and many others.
On AlmaLinux and Rocky Linux
There, fail2ban comes from EPEL: dnf install epel-release and then dnf install fail2ban. The package fail2ban also installs the link with firewalld. The SSH service is called sshd. Switch the jail on yourself in a .local file; unlike on Debian, it is not switched on automatically.
Summary
- Bots try to log in all day long; with keys and password login switched off they cannot get in, and fail2ban also keeps them at a distance.
- A jail is filter + action + thresholds (
maxretry,findtime,bantime); by default 5 attempts in 10 minutes, a 10-minute ban. - Your own settings go in
jail.localorjail.d/*.local, never injail.conf; usebackend = systemd(required on Debian 12). fail2ban-client status sshdshows banned addresses,set sshd unbanipunbans; recidive andbantime.incrementdeal with repeat offenders.- fail2ban does not stop distributed attacks or weak passwords, and does not see Docker ports by itself.
Quiz
Exercise
Exercise Z5.3: Reading an intrusion log. The sample file ssh-journal-1.txt contains a piece of the journal of an SSH server running fail2ban, plus the output of fail2ban-client status sshd. Answer: which address tried the most usernames, which address managed to log in with a key and as which user, which address was banned and at what time, and would that address also have been banned with the default settings (maxretry = 5, findtime = 10m)? The program compares your answers with the fixed answer key. If you have your own server with fail2ban, look at fail2ban-client status sshd there as well.
Further reading
- Securing your VPS: the first five minutes
- Am I blocked? Your IP address and our firewall
- fail2ban, default configuration
jail.conf: https://github.com/fail2ban/fail2ban/blob/master/config/jail.conf - Manual page
jail.conf(5): https://manpages.debian.org/trixie/fail2ban/jail.conf.5.en.html
