Everything we need to block webserver attacks is right in our server logs. Failed SSH login attempts, bots, and automated tools triggering thousands of errors, all of which will show up in our log files. So it’s crazy not to scan those logs for the IP addresses that are causing trouble and block them. There is no reason for an IP to fail an SSH login 100 times when doing something not malicious.

Fail2Ban is a simple tool that parses logs for failed logins and other trigger words, then blocks malicious IPs it discovers. IP blocks happen through the built-in firewall when an IP from the logs reaches a preset number of errors or failures. It does this with pre-built log filters that identify malicious traffic. If you have custom services you can create a custom banning filter using regex expressions. So let’s install Fail2Ban and start getting the most out of our server logs!

This article is the fourth in the Diamond Hard LAMP series.

Installing Fail2Ban

Installing and configuring Fail2Ban is super easy. To receive Fail2Ban alerts we will also need to install SendMail. Otherwise, we will miss out on valuable threat intel!

apt install -yq fail2ban sendmail sendmail-bin

Configuring Fail2Ban

Fail2Ban has two main configuration files we need to be aware of;

  • Fail2Ban’s service configurations (/etc/fail2ban/fail2ban.conf). This configuration file controls how the Fail2Ban’s service runs.
  • Jails configuration file (/etc/fail2ban/jail.conf). Jails control banning IPs for each service, like SSH. Each service we want to monitor and ban malicious traffic will need its own Jail. The default configuration has nearly all the standard Linux services already configured. To start banning malicious traffic we only need to enable the corresponding Jail for the service we have.

Lets make some changes to the default settings!

Fail2Ban Jails

In Fail2Ban you should never edit the “.conf” files. Updates overwrite all our custom settings, destroying all our changes. So, to add our custom configurations we need to create a “.local” copy of the “.conf” file that we want to edit. These “.local” files will hold all the changes we need to make. When Fail2Ban loads up, the “.local” file settings will take precedent over the “.conf” files. This means adding only changes we want to make, and anything not altered will just load from “.conf”.

# Create a ".local" config file to add our custom changes.
touch /etc/fail2ban/jail.local 

Now open up the newly created “/etc/fail2ban/jail.local” and add the following settings. We are tailoring our configurations for a web hosting server. So you should add and remove services based on your needs. If you want to review the prebuilt Jail filters available just open the “jail.conf” file. That file holds a listing of all the Jail services filters that came with Fail2Ban.

# Edit ME! Add this WAN/LAN servers IP
ignoreip =
# This set the Bantime for all enabled Jails. I like 4 weeks.
bantime = 4w
# The interval between scanning logs for new IPs to ban.
findtime = 10m 
# Number of failed tried before we ban the IP.
maxretry = 4
backend = auto
usedns = warn
# Edit ME! Change addr alerts are sent to.
destemail = [email protected]
# Edit ME! Change the sending domain.
sendername = [email protected]
banaction = iptables-multiport
mta = sendmail

enabled   = true

enabled  = true
port     = http,https
filter   = apache-auth
logpath  = /var/log/apache*/*error.log

enabled  = true
port     = http,https
filter   = apache-overflows
logpath  = /var/log/apache*/*error.log

enabled  = true
port     = http,https
filter   = apache-badbots
logpath  = /var/log/apache*/*error.log

enabled  = true
port     = http,https
filter   = apache-nohome
logpath  = /var/log/apache*/*error.log

enabled = true
port    = http,https
filter  = php-url-fopen
logpath = /var/log/apache*/*access.log
Fail2Ban’s Service Configuration

The Fail2Ban’s service configuration file has settings like log level, log file target, database purge time, socket file location, etc… We want to ensure IP Bans are not too short. Fail2Bans by default will purge the IP Ban database every 24-hours, we will extend this to 30-days. Doing so will ensure an IP Ban time for 7-days remains active, and not purged prematurely.

echo -e "[DEFAULT]\ndbpurgeage = 30d" > /etc/fail2ban/fail2ban.local
Fail2Ban’s Configuration Files Permissions

Don’t forget to correctly set the file permissions of the “.local” files we created.

chown root:root /etc/fail2ban/*.local
chmod 644 /etc/fail2ban/*.local

Apply and Test Fail2Ban Settings

Now that we have all our configuration changes done let’s test everything. Restart and enable the new services to run at boot time.

    # Enable SendMail to run at boot and restart the service
    systemctl enable sendmail && systemctl start sendmail
    # Enable Fail2Ban to run at boot and restart the service
    systemctl enable fail2ban && systemctl restart fail2ban

Finally, confirm all the Jails we added are active.

fail2ban-client status

Active Jails will will listed as a result of the above command.

It works!

Final Tips

Most Commonly Needed Admin Commands

To list and manage IP bans you need to use the “fail2ban-client” command. Below I put together a list of the most common day-to-day administrative commands.

# Check Fail2Ban's service status.
fail2ban-client status
# Check a Jails status, and display IPs banned from the service.
# Example: fail2ban-client status <JAIL>
fail2ban-client status sshd
# Unban a banned IP from a Jail
# Example: fail2ban-client set <JAIL> unbanip <IP>
fail2ban-client set sshd unbanip
Troubleshooting Commands

Custom configurations and preference tweaks can on occasion, prevent Fail2Ban from starting. Here is a few helpful commands to find the issue!

# Display Fail2Ban's currently running configurations.
# This can help you see if some of your configs are not loading
fail2ban-client -d
# To get debug information from Fail2Ban while it starts the service, use "fail2ban-client -x"
#  and stop then start the service.
fail2ban-client -x stop ; fail2ban-client -x start
fail2ban-client -x example