Skip to content

How To Install & Configure Fail2Ban On Ubuntu 14.04 LTS To Block Brute Force Attacks Against SSH and Apache Web Server

As you’ve probably heard me say before, if you have a public facing Linux server, meaning one or more open or forwarded ports, Fail2Ban absolutely must be installed. Fail2Ban monitors log files for excessive login attempts, also called Brute Force attacks. They are extremely common place on the internet. I have never had a public facing server that has gone more than a few days without some hacker trying to brute force it. These attacks go like this. Someone writes a script, or uses a program, that reads a bunch of possible usernames from a text file that has nothing but millions of usernames. There is also a text file with millions of passwords. The script will attempt to go through all username and password combinations until it finds one that can login successfully. Obviously, if you get a hundred or more login attempts from one IP address, nothing good will ever come from that IP so it pretty safe to assume it should be blocked, at least for some period of time.

Fail2Ban does precisely this. It constantly watches any log file you tell it to watch, and when a certain number of login attempts are logged from an IP address, Fail2Ban will automatically create an iptables rule to block all traffic from that IP address for a given period of time. Because brute force attacks take a long, long time, blocking one early on pretty much eliminates the possibility of a successful attack. SSH is the most common service / port for brute force attacks, from my experience. With FTP and POP3 (email) coming in second and third. It’s a no-brainer to set up Fail2Ban to automatically block attacks. It gives you much needed protection and security for your servers. So, here we go.

How to Install Fail2Ban on Ubuntu 14.04 LTS (Trusty)

First and foremost, let’s make sure apt is updated.

#  sudo apt-get update

Now we can install Fail2Ban. Since there is an aptitude package already, we will use that to install.

#  sudo apt-get install fail2ban

Surprisingly, that’s all you need to do to install it. You do, however, need to edit the main configuration file for Fail2Ban, which is jail.conf. Lets go ahead and open it up with nano and take a look.

#  sudo nano /etc/fail2ban/jail.conf

There is quite a bit in this configuration file, most of which is inactive by default. Basically, fail2ban has whats called a “jail,” with a “filter” for each service. So, there is a filter for ssh, a filter for ftp, a filter for pop3 and so on. With the exception of the SSH filter (which is the only one enabled by default) each of these filters are disabled by default, so it’s as simple as enabling the filters needed for your specific application. If you only need to protect SSH, you don’t need to do much of anything except tweak the bantime and maxretry variables to your liking. One thing to note, if you have changed the port for SSH to a non standard port, you would need to scroll down to the [ssh] filter and change the port to the appropriate value. This applies to any service if you have modified it to run on a non standard port.

For starters, towards the top of your jail.conf file, you will see a few variables that should probably be tweaked. First up is ignoreip.

# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
# ban a host which matches an address in this list. Several addresses can be
# defined using space separator.

ignoreip = 

Add any IP address or subnet that you use. These IP addresses and subnets are immune to blocking. Each IP/Subnet/Network should be separated by a space, not a comma.

Next up is bantime, findtime, and maxretry.

# "bantime" is the number of seconds that a host is banned.
bantime  = 600

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 600
maxretry = 3

Here is the breakdown of these variables:

  • bantime – How long an IP will be banned if triggered.
  • findtime – The allotted time period where the maxretry counter is running.
  • maxretry – The maximum number of login attempts from an IP, within the findtime, before it’s banned.

So, in a nutshell (with the default values above) the formula works like this: if an IP address tries to log in (maxretry) 3 times in 600 seconds (findtime) it will be banned for 600 seconds (bantime). By the way, 600 seconds is 10 minutes.

Obviously, the default settings are a little bit too aggressive. So, I’m going to ease mine up a bit. They look like this now.

Screen Shot 2015-05-16 at 1.32.49 PM

With these settings, if an IP attempts to login 20 times within 10 minutes, they will be blocked for an hour. Here is a table that might help with the calculations.

  • 600 seconds is 10 minutes
  • 1200 seconds is 20 minutes
  • 3600 seconds is 60 minutes, or 1 hour
  • 43200 seconds is 12 hours, or half a day
  • 86400 seconds is 24 hours, or 1 day

Hopefully that will save you from having to whip out the calculator app. Next we need to change the email address Fail2Ban will send notifications too and the sender name. This is the destemail variable as well as sendername. So, scroll down and find them.

# Destination email address used solely for the interpolations in
# jail.{conf,local} configuration files.
destemail = [email protected]

# Name of the sender for mta actions
sendername = Fail2Ban

This is pretty self explanatory. Change [email protected] to your email address, and Fail2Ban can be left as is or changed. I suggest change it to something that will identify the server you’re working with. If fail2ban is installed on multiple servers, it’s nice to instantly know which one you are receiving a notification from.

Screen Shot 2015-05-16 at 1.40.21 PM

The last global variable we want to change is the action variable. Fail2Ban has 3 default actions you can choose from when an IP ban is triggered.

  • action_ will ban the IP
  • action_mw will ban the IP and send an email with a whois report
  • action_mwl will ban the IP, send an email with a whois report, and include any relevant lines of the log file

I like having as much information as possible, so I will use action_mwl. This is set at the action variable, which looks like this.

action = %(action_)s

Screen Shot 2015-05-16 at 1.46.19 PM

This is the line we want to change. It should look like this after you change it.

action = %(action_mwl)s

Screen Shot 2015-05-16 at 1.47.20 PM

The rest of the log file deals with the filters that correspond to each service you want Fail2Ban to protect and monitor. Any global options that are specified for an individual jail will override the global setting, such as the maxretry variable. So, make sure you set maxretry to match the global variable if its specified for an individual filter.

To enable a filter, you just need to toggle the enabled variable from False to True. Like I said before, SSH is enabled by default. Just make sure the maxretry is set how you want it to be. As an example, I’m going to enable the Apache filter, so the Apache web server is protected. If you use NGINX, there is a filter for that as well. So, scroll down to to [apache]. It looks like this by default.

Screen Shot 2015-05-16 at 1.53.08 PM

To enable it, change the enabled variable, and double check the maxretry variable. I’ve enabled mine and it looks like this.

Screen Shot 2015-05-16 at 1.54.24 PM

If your apache / httpd log file is not in the default location, /var/log/ be sure to update the logpath variable. Now that we have our jail.conf file configured to our liking, we can save and exit (CTRL-X, Y). Now we need to restart the Fail2Ban service to apply the changes we’ve made.

#  sudo service fail2ban stop

#  sudo service fail2ban start

Screen Shot 2015-05-16 at 1.58.36 PM

You should get an [OK] after starting the service back up, which means there are no errors in your jail.conf file. If you get an error when trying to start it, double check your jail.conf. There is more than likely a typo somewhere in there. If you run into any problems, please post in the comments and I’ll do my best to help. Thanks!