Blocking Brute-Force Attacks with Fail2Ban

Learn how to install and configure Fail2Ban to automatically detect and block brute-force login attempts against SSH, web servers, and other services.

Fail2Ban watches your log files for repeated failed login attempts and automatically blocks the offending IP address by inserting a firewall rule.

Example: Someone tries to brute-force SSH 5 times within 10 minutes. Fail2Ban detects the failures in /var/log/auth.log and adds an iptables rule banning that IP for an hour. When the ban duration expires, it removes the rule automatically.

Fail2Ban works for any service that logs failures: SSH, WordPress wp-login.php, Apache, Nginx, MySQL, FTP, and mail servers.

How It Works

  1. You define a jail - a service to watch, the log file to monitor, a regex pattern to match failures, and thresholds (max retries, time window, ban duration)
  2. Fail2Ban tails the log file and counts pattern matches per IP address
  3. When an IP hits the retry threshold, it executes a ban action (iptables -I INPUT -s <ip> -j DROP)
  4. After the ban duration expires, the IP is automatically unbanned

Installation

sudo apt install fail2ban -y

Configuration

Fail2Ban ships with a default config at /etc/fail2ban/jail.conf. You should not edit this file directly - it gets overwritten on upgrades. Create a local override instead:

sudo nano /etc/fail2ban/jail.local

A basic jail.local enabling SSH and Apache protection:

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

[sshd]
enabled = true

[apache-auth]
enabled = true

The [DEFAULT] section sets global defaults for all jails:

  • bantime - how long to ban an IP after it hits the threshold (e.g. 1h, 24h, 1w, -1 for permanent)
  • findtime - the time window in which failures are counted (e.g. 10m means 5 failures within any 10-minute window)
  • maxretry - number of failures before banning

Individual jail sections can override any of the defaults.

Enable and Start

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Useful Commands

Check the status of all active jails:

fail2ban-client status

Check the status of a specific jail (shows banned IPs, failure counts):

fail2ban-client status sshd

Unban an IP address:

fail2ban-client set sshd unbanip 1.2.3.4

Watch the Fail2Ban log in real time:

tail -f /var/log/fail2ban.log

Reload config after changes to jail.local:

sudo fail2ban-client reload