Troubleshooting

Fail2ban not banning? Common causes and fixes

Fail2ban is running but attackers are never banned. Work through the usual causes, from the wrong log backend and log path to a ban action that does not fit your firewall or a custom SSH port.

IntermediateLinux server6 min read

Fail2ban can look healthy, with the service active and jails listed, while it never bans a single address. Almost always the cause is one of a handful of mismatches: it reads the wrong log, its filter does not fit the log lines, or its ban goes into a firewall your server does not use. This guide checks each one in order, from quickest to most involved.

Before you start

  • A Linux VPS running Ubuntu 22.04 or 24.04, Debian 12, or AlmaLinux or Rocky Linux 8 or 9, with Fail2ban installed.
  • A user with sudo.
  • Your own IP in ignoreip in /etc/fail2ban/jail.local, so a fix that suddenly starts working does not ban you.
  • A second way in. If a ban does catch you, the browser console in your VPS provider's control panel still works.

Step 1: Is the service and jail running?

Bash
sudo systemctl status fail2ban --no-pager
sudo fail2ban-client status

If the service failed, read why:

Bash
sudo journalctl -u fail2ban -n 50 --no-pager

If your jail is missing from Jail list, it is not enabled, or it failed to start. Check the config with sudo fail2ban-client -t. A common message is Have not found any log file for sshd jail, which leads straight to step 2.

Step 2: Does the jail read the right log?

Look at what the jail is watching:

Bash
sudo fail2ban-client status sshd

The Filter section shows either File list: (a log file) or Journal matches: (the systemd journal).

  • Debian 12 does not install rsyslog by default, so /var/log/auth.log does not exist. A file-based sshd jail has nothing to read. Fix it with the journal backend.
  • Ubuntu writes /var/log/auth.log, and AlmaLinux and Rocky write /var/log/secure. File-based jails work there, but the journal works too.
  • Apps with their own logs, such as Nginx sites with per-site files, need the exact logpath that the app writes to.

Switch SSH to the journal in /etc/fail2ban/jail.local:

INI
[sshd]
enabled = true
backend = systemd

On Debian and Ubuntu, the journal backend needs python3-systemd:

Bash
sudo apt install python3-systemd
sudo fail2ban-client -t && sudo fail2ban-client reload

Step 3: Does the filter match the log lines?

A jail can read the right log and still match nothing. Test it with fail2ban-regex, which reports matches without banning.

For a log file:

Bash
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

For the journal:

Bash
sudo fail2ban-regex systemd-journal sshd

Look at the Lines: summary at the end. On a public server, matched should be well above zero. If it is zero:

  • You tested a quiet log. Generate a failure from another network and test again.
  • The log format changed, for example after an OpenSSH upgrade. Update Fail2ban to the current distribution package, which ships updated filters.
  • Timestamps are not recognised. Check that Date template hits is above zero.

Tip: The sshd filter has a mode setting (normal, ddos, extra, aggressive). aggressive catches more kinds of failed connection. Set it with mode = aggressive in the [sshd] section if normal mode misses real attacks.

Step 4: Does the ban reach your firewall?

If fail2ban-client status sshd shows banned addresses but they can still connect, the ban is not landing in the firewall that actually filters traffic.

Check which action Fail2ban uses:

Bash
sudo fail2ban-client -d | grep -i "banaction\|actionban" | head
grep -r banaction /etc/fail2ban/jail.local /etc/fail2ban/jail.d/

Match it to your firewall:

  • firewalld (AlmaLinux and Rocky): use firewallcmd-rich-rules or firewallcmd-ipset. The fail2ban-firewalld package sets this for you.
  • nftables only: use nftables-multiport (or nftables).
  • UFW: iptables-multiport usually works because UFW uses the same backend, or use the ufw action.

Set it in jail.local:

INI
[DEFAULT]
banaction = firewallcmd-rich-rules
banaction_allports = firewallcmd-rich-rules

Then confirm the bans appear in the ruleset. For firewalld, sudo firewall-cmd --list-rich-rules. For nftables, sudo nft list ruleset | grep -A5 f2b. See Use Fail2ban with firewalld or nftables for more detail.

Warning: Never run two firewall managers at once, such as UFW and firewalld. Bans and allow rules end up in different places, and you can lock out SSH. Pick one and disable the other.

Step 5: Is the port right?

Fail2ban only blocks the ports in the jail's port setting. If SSH runs on 2222 and the jail says port = ssh (22), attackers are "banned" on a port nobody uses and keep hitting 2222.

INI
[sshd]
enabled = true
port    = 2222
backend = systemd

Reload, then check the rule names the right port in your firewall output. See Change the SSH port safely.

Step 6: Smaller causes

  • The attacker is in ignoreip: a wide range like 0.0.0.0/0 or a big provider block in ignoreip exempts attackers too. Keep it to your own addresses.
  • maxretry and findtime too loose: a slow attack, one try every few minutes, may never hit maxretry within findtime. Widen findtime or enable the recidive jail.
  • Traffic arrives through a proxy: web jails see the proxy's address unless real IP logging is set up.
  • Docker containers: traffic to published container ports can bypass rules in the normal INPUT chain, so bans may not apply to it.

Check it works

From another network, such as a phone hotspot, make several failed SSH logins. Then:

Bash
sudo fail2ban-client status sshd
sudo tail -n 20 /var/log/fail2ban.log

You should see Found lines, a Ban line, the address in the banned list, and new connections from it timing out. Unban it afterwards with sudo fail2ban-client set sshd unbanip IP.

Troubleshooting

  • Have not found any log file: the path is wrong or the file does not exist. Use backend = systemd, or fix logpath.
  • fail2ban-regex matches but no bans: look in fail2ban.log for ERROR lines from the action. A missing ipset or nft command, or a firewall that is not running, makes the ban fail.
  • Banned in Fail2ban but still connecting: wrong banaction for your firewall, or wrong port.
  • Everything worked before an OS upgrade: check the backend and package versions again. Log locations and default actions can change between releases.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.