How to configure Fail2Ban in Ubuntu 16.04

If you have set up a Linux server, you may be unaware how many times someone has attempted to compromise it. Any server that is open to the web has surely had bots trying to gain access to them by bombarding the server with default username and password guesses. They attempt to exploit your SSH and web ports to gain access. Thankfully fail2ban can help stop these login attempts.

SSH is still a very secure network protocol to access a remote server. Once connected to a remote server, all communications between you and the host is cryptographically secured, much like HTTPS traffic is secured with SSL. Setting up ssh to connect to a remote server does have some inherent risks, however, since a port is required to be publicly open to initiate a session. These risks can be mitigated with fail2ban, a service that automatically modifies iptables based on the number of failed login attempts from an IP address.

If fail2ban determines that an IP address has unsuccessfully attempted to login enough times, it will add an entry is added to iptables. Iptables, a command line firewall utility, will then drop any incoming connection from the IP address. This will prevent a brute force attack by limiting the number of attempted logins that they are able to perform.

Installing and Configuring fail2ban:


The first step is to install fail2ban from the Ubuntu repository:

sudo apt install fail2ban

Fail2ban is installed into the /etc/fail2ban directory. We want to move our active working directory there with cd /etc/fail2ban. Inside this directory we can see there is a file called jail.conf, this is the configuration file for the fail2ban rules. We don’t want to edit this file directly, because any package updates will overwrite our changes. Instead, we should create a new file called jail.local.

We can choose to manually create and edit the new file, or we can use awk to copy jail.conf to jail.local with a comment at the beginning of each line. We can then simply uncomment any line we wish to change from the default values.

awk '{ printf "# "; print; }' /etc/fail2ban/jail.conf | sudo tee /etc/fail2ban/jail.local

With this new jail.local file we can look though and decide how we should modify any rules to fit our needs. I will be going over my jail.local file in sections. You can choose to add or uncomment these changes as needed.

General Settings:

[DEFAULT]

ignoreip = 127.0.0.1/8 192.168.0.0/16
bantime  = 31536000
findtime  = 86400
maxretry = 9

[jail_to_enable]
enable = true

Under the [DEFAULT] section, we can see that you can add IP addresses to never be banned by ignoring their failed attempts. Since  127.0.0.1 is ignored by default, which is the localhost, this will prevent you from locking yourself out of the machine. IP addresses can be individual addresses, or can be ranges of IP addresses with CIDR subnet mask. 192.168.0.0/16 would cause any IP from 192.168.x.x to be ignored, and 192.168.0.0/24 would cause any IP from 192.168.0.x to be ignored. These prevent any machine in your local area network from being banned.

The bantime is pretty simply how long you want an IP address to be banned for in seconds. Alternativly, you can use a value of -1 to ban IP addresses forever. The maxretry variable sets the number of tries a client has to authenticate within a window of time defined by findtime, before being banned. With the default settings, the fail2ban service will ban a client that unsuccessfully attempts to log in 3 times within a 10 minute window.

In order to activate fail2ban jails to work, we must set enable to true under the [jail_to_enable] section. This will enable fail2ban to use any of the jails that we will set up and enable. Since the [SSH] section is enabled by default, we will only need to add any additional jails to be used, such as the variety of apache jails or the WordPress jail.

Email settings:

destemail = root@localhost
sender = Fail2Ban
mta = sendmail

action = %(action_mwl)s

The next section, we can setup fail2ban to email us any time it bans an ip. We can set the destemail to be the email we want to receive the notices, sender will set the value of the “From” field in the email, and the mta variable is which email service will send the mail. By default, the email sender is sendmail, and to enable emails, we must install it.

sudo apt install sendmail

Once installed if you would like to configure email alerts, add or uncomment the action item and change its value from %(action_)s to %(action_mw)s. If you want the email to include the relevant log lines, you can change it to %(action_mwl)s. Make sure you have the appropriate mail settings configured if you choose to use mail alerts.

Additional Jails:

[apache-auth]
enable = true
port = http,https
logpath = /var/log/apache/error.log
maxretry = 3
findtime = 600

[apache-noscript]
enable = true

[apache-overflows]
enable=true

[apache-badbots]
enable = true

[apache-botsearch]
enable = true

[apache-nohome]
enable = true

[php-url-fopen]
enable = true
logpath = /var/log/apache2/access.log

If you are running a webserver with Apache, there are some useful fail2ban jails that are built in. We just need to enable them if we wish to use them, and change the log path if they are not in their default locations: /var/log/apache/error.log for the error log and /var/log/apache/access.log for the access logs. If the log files are default, we do not need to include the logpath line. Additionally, we can redefine bantime, maxretry, and findtime for each jail if we choose to.

  • [apache-auth] detects password authentication failures.
  • [apache-noscript] prevents potential search for exploits and php vulnerabilities.
  • [apache-overflows] prevents Apache overflow attempts by entering in long URLs.
  • [apache-badbots] detects spammer robots crawling email addresses.
  • [apache-botsearch] detects failures to execute non-existing scripts that are associated with several popular web services e.g. webmail, phpMyAdmin, WordPress.
  • [apache-nohome] prevents access to any home directory on a server.
  • [php-url-fopen] blocks attempts to use certain PHP behavior for malicious purposes. 

    There is also a WordPress plugin that creates logs based on wp-admin logins for fail2ban. There are a few additional steps to configure fail2ban to work with wordpress, and there is a well written guide on their install page.

Configuring iptables for fail2ban:


To configure our ip tables, we will need to stop the fail2ban service while we make changes.

sudo service fail2ban stop

Form here, we should add some basic firewall settings to our iptables. This will allow only connections on ports 22, 80, and 443, and drop all other connections.

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
sudo iptables -A INPUT -j DROP

We can view our iptables with:

sudo iptables -S

We can verify the last 5 lines are the ones we added to the table.

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j DROP

Once we double check the rules are correct, we need to reconfigure the table so that it is persistent. To do that we first need to download an iptables package:

sudo apt install iptables-persistent

Then we can simply reconfigure our iptables so that they remain persistent though server restarts.

sudo dpkg-reconfigure iptables-persistent

We can now restart fail2ban:

sudo service fail2ban start

If we look at the iptable now, we can see fail2ban has inserted a few rules, in accordance with what we enabled in the jails.local file.

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N f2b-sshd
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
-A INPUT -j DROP
-A f2b-sshd -j RETURN

That’s it for the installation and configuration! In the final step we can verify that everything is working as intended.

Verifying Installation:


Checking the Status of Ports:

With fail2ban installed, all ports besides 22, 80, and 443 should be blocked. We can verify the status of our ports with netcat, which is installed with Ubuntu by default. Netcat works simmilarly to the old telnet commands, and we can use it to check if a port is open or closed. We can even input a range of ports to check, and netcat will scan through each port for us. We can test the ports even from the local machine. To test the first 30 ports as an example, we can use the following command:

nc -vz 127.0.0.1 1-30

We just need to verify that port 22 is still open, and port 80 and 443 if you are using a webserver, and that all other ports are closed.

View failed IP connections:

If we want to view all of the IPs that have entered wrong credentials, we can use the following command:

sudo cat /var/log/auth.log | grep {jail}.*Failed

Make sure to replace {jail}, for example to check for failed SSH connections, use sshd.

 Vew all IP bans:

If we want to view all of the IPs that fail2ban has caught, we can use the following commands:

sudo netstat -an | grep 192.168.0.
sudo iptables -S
sudo iptables -L -n
sudo fail2ban-client status

Unban an IP:

If an IP accidentally gets banned, we should know how to unban it. fail2ban has a simple command to unban any IP from any jail. Just replace the name of the jail and the IP address in the command:

sudo fail2ban-client set {jail} unbanip {ip_address}

For example, to unban an IP from SSH connections, you should replace use sshd as the name of the jail.

Additionally, if you have a spare computer to login to the server, you could purposefully enter in the wrong credentials. We want to verify that you get a timeout from the server, which means that it is ignoring our log-in attempts. You can unban the IP of your computer after you test it.

Conclusion:


We can now feel much better about the security of our server. Hopefully this guide helps you install and configure fail2ban to prevent unauthorized access. If you have any questions or comments, feel free to leave them below!

Leave a Reply

Your email address will not be published. Required fields are marked *