Fail2ban’s core mechanism is surprisingly simple: it monitors log files for patterns indicating malicious activity, and when it finds enough of them, it temporarily bans the offending IP address.

Let’s watch it in action. Imagine an attacker is trying to guess FTP credentials on your server. They’ll hit your vsftpd.log file with repeated failed login attempts.

Mon Oct 26 10:30:01 2023 [PID 1234] [user] FAIL LOGIN: [IP 192.168.1.100]
Mon Oct 26 10:30:02 2023 [PID 1235] [user] FAIL LOGIN: [IP 192.168.1.100]
Mon Oct 26 10:30:03 2023 [PID 1236] [user] FAIL LOGIN: [IP 192.168.1.100]
Mon Oct 26 10:30:04 2023 [PID 1237] [user] FAIL LOGIN: [IP 192.168.1.100]
Mon Oct 26 10:30:05 2023 [PID 1238] [user] FAIL LOGIN: [IP 192.168.1.100]

Fail2ban, configured to watch for these patterns, sees the repeated "FAIL LOGIN" entries from 192.168.1.100. After a predefined number of failures within a specific time window, Fail2ban triggers an action, typically adding a firewall rule to block that IP.

This solves the problem of automated, low-and-slow brute-force attacks that might otherwise go unnoticed until a successful compromise. Fail2ban acts as an automated, proactive defense layer.

Internally, Fail2ban works by reading configuration files in /etc/fail2ban/. The primary files are jail.conf (the main configuration) and jail.d/*.conf (for custom overrides). It also uses filter.d/ for regex patterns and action.d/ for the commands to execute.

You control Fail2ban’s behavior through these configuration files. Key settings include:

  • [DEFAULT] section: Global parameters.
    • bantime: How long an IP is banned (e.g., 1h for 1 hour, 1d for 1 day, -1 for permanent).
    • findtime: The time window within which failures are counted (e.g., 10m for 10 minutes).
    • maxretry: The number of failures within findtime that triggers a ban (e.g., 5).
  • Specific jails (e.g., [vsftpd]) for individual services.
    • enabled = true: Activates the jail.
    • port: The service port (e.g., ftp, 21).
    • filter: The name of the filter file in filter.d/ (e.g., vsftpd).
    • logpath: The path to the log file to monitor (e.g., /var/log/vsftpd.log).
    • action: The action to take (e.g., %(action_mwl)s which means "ban and send mail with whois report and relevant log lines").

To detect FTP brute-force attempts, you’d typically create or modify a jail for vsftpd.

First, ensure you have a filter for vsftpd in /etc/fail2ban/filter.d/vsftpd.conf that looks something like this:

[Definition]
failregex = ^%(_daemon)s .*\[PID \d+\] \[.*\] FAIL LOGIN: \[IP <HOST>\]$
ignoreregex =

This regex specifically targets lines in your FTP server logs that indicate a failed login attempt and capture the offending IP address in <HOST>.

Then, in your /etc/fail2ban/jail.local (or a file in jail.d/), you’d define the jail itself:

[vsftpd]
enabled = true
port    = ftp
filter  = vsftpd
logpath = /var/log/vsftpd.log
maxretry = 6
findtime = 10m
bantime = 1h

This configuration tells Fail2ban to:

  1. Enable the vsftpd jail.
  2. Monitor the FTP port (port 21).
  3. Use the vsftpd filter defined previously.
  4. Watch the /var/log/vsftpd.log file for matching patterns.
  5. Ban any IP that makes 6 or more failed login attempts within a 10-minute window.
  6. Keep the ban in place for 1 hour.

After applying these changes, you’d restart Fail2ban: sudo systemctl restart fail2ban.

You can check the status of your jails with sudo fail2ban-client status. To see if an IP is banned, use sudo fail2ban-client status vsftpd. If you want to manually unban an IP, use sudo fail2ban-client set vsftpd unbanip 192.168.1.100.

The most surprising thing about Fail2ban is that it doesn’t analyze the intent of a connection; it only reacts to patterns in log files. This means a legitimate user who makes a few typos could inadvertently get themselves banned.

The action parameter is where the magic happens, and it’s more powerful than just blocking IPs. For example, %(action_mwl)s is a common action that not only bans the IP but also sends an email to the administrator containing a whois lookup for the banned IP and the relevant log lines that triggered the ban. This gives you context for why the ban occurred, which is crucial for distinguishing between automated attacks and accidental misconfigurations or user errors.

The underlying mechanism for banning is usually iptables or nftables. Fail2ban dynamically adds rules to your firewall. For instance, a ban might result in an iptables rule like: -A fail2ban-vsftpd -s 192.168.1.100/32 -j DROP. This rule is inserted at the top of the fail2ban-vsftpd chain, ensuring that any traffic from the banned IP destined for the FTP port is immediately dropped before it even reaches the vsftpd service.

The next hurdle you’ll likely encounter is dealing with distributed brute-force attacks where attackers rotate through many IP addresses, making maxretry less effective.

Want structured learning?

Take the full Ftp course →