Fail2Ban

Protect Linux servers from brute-force attacks by banning IPs that show malicious signs in log files using Fail2Ban.

Fail2Ban

Fail2Ban is an intrusion prevention tool that monitors log files for malicious patterns and automatically bans offending IP addresses by updating firewall rules on Linux servers.

What Fail2Ban Does and When to Use It

Fail2Ban scans log files such as /var/log/auth.log, Nginx access logs, and Apache error logs for patterns that indicate brute-force attacks, credential stuffing, or exploit scanning. When Fail2Ban detects a configurable number of failed attempts from a single IP address within a time window, it adds a firewall rule to block that IP for a specified ban duration.

Fail2Ban works with multiple firewall backends: iptables, nftables, and UFW (Uncomplicated Firewall). It ships with pre-configured "jails" for common services — SSH, Apache HTTP Server, Nginx, Postfix, Dovecot, and others. Each jail defines which log file to watch, which regex filter to apply, and which ban action to execute.

Fail2Ban is not a replacement for strong authentication practices. It mitigates automated attacks but cannot stop an attacker who has valid credentials. Use Fail2Ban alongside SSH key-based authentication, rate limiting, and proper firewall rules. For official documentation, see fail2ban.org.

How to Install Fail2Ban

Installation commands differ by distribution. Fail2Ban requires Python 3.6 or higher since version 1.1.0.

=== "Ubuntu / Debian"

sudo apt update
sudo apt install fail2ban

=== "RHEL / CentOS / Fedora"

sudo dnf install epel-release
sudo dnf install fail2ban

=== "Arch Linux"

sudo pacman -S fail2ban

Enable and start Fail2Ban after installation:

sudo systemctl enable --now fail2ban.service

Core Concepts of Fail2Ban

Fail2Ban Jails

A jail is the core configuration unit in Fail2Ban. Each jail monitors a specific service by combining a log file path, a regex filter, a ban action, and thresholds for maxretry, findtime, and bantime. Jails are defined in /etc/fail2ban/jail.local (user overrides) or /etc/fail2ban/jail.d/*.conf (drop-in files). Never edit jail.conf directly — package updates overwrite it.

Fail2Ban Filters

A filter is a file in /etc/fail2ban/filter.d/ containing regex patterns ( failregex) that match failed authentication lines in logs. Fail2Ban ships with filters for sshd, nginx-http-auth, apache-auth, postfix, and dozens of other services. Custom filters can be tested with fail2ban-regex before activating a jail.

Fail2Ban Actions and Firewall Backends

An action defines how Fail2Ban bans and unbans an IP. The default action on most systems uses iptables-multiport. On modern distributions (Debian 13+, Ubuntu 24.04+), the default firewall is nftables — set banaction = nftables-multiport in jail.local to match. If UFW is the active firewall, set banaction = ufw.

Fail2Ban Backend for Log Reading

The backend setting in jail.local controls how Fail2Ban reads log files. On systemd-based distributions, set backend = systemd so Fail2Ban reads directly from the systemd journal instead of polling text log files. This is faster and more reliable for services that log to the journal.

Common Tasks with Fail2Ban

How to Enable the SSH Jail in Fail2Ban

Create /etc/fail2ban/jail.local with an SSH jail definition. Fail2Ban monitors the SSH log for failed login attempts and bans offending IPs:

[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd

[sshd]
enabled = true
port = ssh

Restart Fail2Ban to apply the new jail configuration:

sudo systemctl restart fail2ban

How to Check Fail2Ban Jail Status

The fail2ban-client status command lists all active jails. Add a jail name to see banned IPs and ban statistics:

sudo fail2ban-client status
sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 3
|  |- Total failed:     127
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 2
   |- Total banned:     18
   `- Banned IP list:   203.0.113.45 198.51.100.12

How to Manually Ban or Unban an IP in Fail2Ban

Ban an IP manually with fail2ban-client:

sudo fail2ban-client set sshd banip 203.0.113.45

Unban a mistakenly blocked IP:

sudo fail2ban-client set sshd unbanip 203.0.113.45

How to Test a Fail2Ban Filter Against a Log File

Verify that a filter's regex matches the expected log entries before enabling a jail. fail2ban-regex tests a filter against a log file and reports matches:

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

Fail2Ban Troubleshooting

Error / SymptomCauseFix
Fail2Ban bans IPs but they are not blockedFirewall backend mismatch (iptables rules on an nftables system)→ Full article
iptables: not found in Fail2Ban logiptables is not installed; system uses nftables→ Full article
Fail2Ban does not detect failed loginsWrong backend setting or incorrect log path→ Full article
Locked out of own server by Fail2BanOwn IP was banned by the sshd jail→ Full article

UFW (Uncomplicated Firewall) provides a frontend to iptables and works as a ban action backend for Fail2Ban. See the UFW article.

SSH runs as the primary service protected by Fail2Ban's sshd jail. See the SSH article.

Nginx access and error logs can be monitored by Fail2Ban with custom jails. See the Nginx article.