Automate server intrusion detection and banning with Fail2ban

Monitors server access logs and automatically bans IP addresses of bots and attackers

A Fail2Ban installation monitors server access logs and automatically bans IP addresses of bots and attacking users in iptables. Fail2Ban analyses server logs and identifies a pattern where a suspicious user or bot is trying to access restricted areas on the server. Brute force attacks repeatedly fail and use combinations of login credentials on after another. Fail to ban can detect failed login attempts on SSH and Apache webserver.

Fail2Ban Installation

Installation is straight forward update apt-get and run instal fail2ban as a root user. Theses are Debian/Ubuntu commands for CentOS yum would replace apt-get and paths/locations might differ for configuration files. Check this tutorial for non-Debian operating systems.

sudo apt-get update
sudo apt-get install fail2ban

Fail2Ban Configuration

Fail2Ban can keep server admin updated with emails but to keep it simple, let’s not configure this additional feature. The configuration file /etc/fail2ban/fail2ban.conf is superseded by fail2ban.local file. So this local config file needs to be created to keep additional settings. Here is part of the default installation config file.

# Option: loglevel
# Notes.: Set the log level output.
#         CRITICAL
#         ERROR
#         WARNING
#         NOTICE
#         INFO
#         DEBUG
# Values: [ LEVEL ]  Default: ERROR
loglevel = INFO
logtarget = /var/log/fail2ban.log
# Options: dbfile
# Notes.: Set the file for the fail2ban persistent data to be stored.
#         A value of ":memory:" means database is only stored in memory 
#         and data is lost when fail2ban is stopped.
#         A value of "None" disables the database.
# Values: [ None :memory: FILE ] Default: /var/lib/fail2ban/fail2ban.sqlite3
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
# Options: dbpurgeage
# Notes.: Sets age at which bans should be purged from the database
# Values: [ SECONDS ] Default: 86400 (24hours)
dbpurgeage = 86400

Fail2ban focuses on failed SSH login attempts by default. Using custom config file jails for HTTP web server like Apache, FTP and mail server can be enabled.

Fail2Ban Apache Jail Configuration

enabled  = true
port     = http,https
logpath  = /var/log/apache2/error.log
maxretry = 3
findtime = 600
bantime = 1h

So here we have set up fail2ban to look apache2 error logs for brute force attack using one password after another. Three failed login attempts within 600 seconds would lead to an IP address ban for an hour. Restart fail2ban for the changes to take effect sudo systemctl restart fail2ban. To enable fail2ban service to start with boot use sudo systemctl enable fail2ban.

Other Apache error log jails

Apache no script

port     = http,https
logpath  = %(apache_error_log)s
ignoreip = localhost or an IP

Fail2ban analyses errors of not found .php, .asp, .pl scripts. Client attempting to exploit known scripts are banned.

Apache overflows

logpath  = %(apache_error_log)s
maxretry = 2

Detects apache buffer overflow attempts by the client using long suspicious URLs.

Apache no home

port     = http,https

Detects failures to find a home directory on a server.

enabled  = true
port     = http,https
maxretry = 2

Alternative to apache-noscript filter this filter aims at blocking specific URLs, script or webservices.

Apache access log jails

Beware, access logs of busy websites can be huge. Setting Fail2ban to monitor access log can have a negative impact on server performance. So think about costs and benefits of access log jails before enabling them.

Apache bad bots

Bans bots identified as spammer robots crawling the web for email addresses.

port     = http,https
logpath = %(apache_access_log)s

PHP URL fopen

Matches and blocks fopen URL PHP injection attacks

port    = http,https

Webmail jails

Jails for roundcude, openwebmail and horde are available, just add the location of log file in these jails.

port     = http,https
logpath  = %(roundcube_errors_log)s
#if roundcube logs to journal then use following.
#backend = %(syslog_backend)s
port     = http,https
logpath  = /var/log/openwebmail.log
port     = http,https
logpath  = /var/log/horde/horde.log

Fail2ban custom filters and jail for WordPress

Error logs have multiple failed requests to WordPress login URLs or files like wp_login.php. This blog post creates a custom regular expression to scan failed WordPress logins in the error log. Using this RegEx a new filter file is created in Fail2ban directory. Once the filter is in place a [wordpress] jail can be added in jail.local. You can easily create your own filters with custom RegEx. Try online regular expression services like with your error log to create a regular expression.

Fail2ban client and commands

Use Fail2ban client to setup configuration or check status of jail and banned IP addresses.

  • Check status of Fail2ban
    sudo fail2ban-client status
  • Check status of Apache jail
    sudo fail2ban-client status apache
  • Ban an IP address directly with client
    sudo fail2ban-client set apache banip x.x.x.x
  • Similarly unban an IP address
    sudo fail2ban-client set apache unbanip x.x.x.x
  • Restart after editing jail configuration for changes to take effect
    sudo systemctl restart fail2ban
  • Check firewall rules added to iptables
    sudo iptables -L
  • Start fail2ban on boot
    sudo systemctl enable fail2ban

I am also on Twitter. You can follow me there as I regularly tweet about my journey.


  1. How To Protect an Apache Server with Fail2Ban on Ubuntu 14.04 — By Justin Ellingwood,
  2. Fail2ban jail configuration —
  3. Set Up Fail2ban To Protect An Apache Web Server — hitjethva,
  4. A Tutorial for Using Fail2ban to Secure Your Server —