Setup Fail2ban, block brute force attacks

4 minute read

fail2ban is a program protecting your server from brute force attack. When fail2ban detects a possible attack attempt, the source ip is banned.

Resources

Install

sudo apt-get update
sudo apt-get install fail2ban

Quick configuration

fail2ban reads the configuration in jail.conf then the configuration in jail.local. Any configuration written in jail.local will override the default configuration in jail.conf.

When fail2ban is updated, jail.conf is also updated, but jail.local is left as it is.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local

Here is a minimalistic configuration in jail.local:

/etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8
ignorecommand =
bantime  = 7200
findtime  = 3600
maxretry = 5
destemail = sammy@gmail.com
sender = root@localhost
mta = sendmail

Apply configuration with:

sudo fail2ban-client reload

Verify that fail2ban is running with:

sudo fail2ban-client status
# Output
sudo fail2ban-client status
Status
|- Number of jail:	1
`- Jail list:	sshd

We can see that Apache is missing.

Monitor Apache Logs

In this section we configure and enable apache jails. Once they’re all configured you can implement them by restarting fail2ban:

sudo service fail2ban restart

[apache] jail

This jail will take care of banning basic authentication failures. Modify /etc/fail2ban/jail.local to add the following lines

/etc/fail2ban/jail.local
[apache]

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

[apache-overflows] jail

The [apache-overflows] jail is used to block clients who are attempting to request unusually long and suspicious URLs. These are often signs of attempts to exploit Apache by trying to trigger a buffer overflow. You can enable this jail if you wish to prevent these types of attacks:

/etc/fail2ban/jail.local
[apache-overflows]

enabled = true

[apache-badbots] jail

Stops some known malicious bot request patterns. Usually configured the same way as [apache-overflows]

/etc/fail2ban/jail.local
[apache-overflows]

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

[apache-badbots]

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

[apache-nohome] jail

If you do not use Apache to provide access to web content within users’ home directories, you can copy and paste again and change the jail and filter names to apache-nohome:

/etc/fail2ban/jail.local
[apache-overflows]

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

[apache-badbots]

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

[apache-nohome]

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

[php-url-fopen] jail

Lastly, if you are using Apache with PHP, you may want to enable the [php-url-fopen] jail, which blocks attempts to use certain PHP behavior for malicious purposes. You will likely have to change the logpath directive to point the correct access log location (on Ubuntu, the default location is /var/log/apache2/access.log). You can use a pattern similar to the one that matches the error log in the other jails:

/etc/fail2ban/jail.local
[php-url-fopen]

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

Implementing Apache jails

sudo service fail2ban restart
sudo fail2ban-client status
# Output
Status
|- Number of jail:	6
`- Jail list:	apache, apache-badbots, apache-nohome, apache-overflows, php-url-fopen, sshd

You can see that fail2ban has modified your firewall rules to create a framework for banning clients. Even with no previous firewall rules, you would now have a framework enabled that allows fail2ban to selectively ban clients by adding them to purpose-built chains:

sudo iptables -S
sudo fail2ban-client status apache
Status for the jail: apache
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	0
|  `- File list:	/var/log/apache2/shaarli_error.log /var/log/apache2/error.log /var/log/apache2/wekan_error.log /var/log/apache2/wallabag_error.log /var/log/apache2/owncloud_error.log /var/log/apache2/house_error.log /var/log/apache2/bookmarks_error.log
`- Actions
   |- Currently banned:	0
   |- Total banned:	0
   `- Banned IP list:

Monitor Wallabag logs

Source

Create a new filter

sudo touch /etc/fail2ban/filter.d/apache-wallabag.conf

Edit it with vim

sudo vim /etc/fail2ban/filter.d/apache-wallabag.conf

Add the following lines to the file:

/etc/fail2ban/filter.d/apache-wallabag.conf
# Filter monitoring wallabag authentication attempts
[Definition]
failregex =  <HOST> .*"POST /login_check HTTP/.*" 302.*
ignoreregex =

Then modify the jail.local file to add the [apache-wallabag] jail.

/etc/fail2ban/jail.local
[apache-wallabag]
enabled = true
port    = http,https
filter  = apache-wallabag
logpath = /var/log/apache2/wallabag_access.log
maxretry = 3

Monitor Owncloud logs

Here is an example log line for a failed authentication attempt:

{"reqId":"wtylKltXff00rmCbPKqV","level":2,"time":"2017-08-03T07:19:43+00:00","remoteAddr":"86.233.96.223","user":"--","app":"core","method":"POST","url":"\/index.php\/login?user=test","message":"Login failed: 'test' (Remote IP: '86.233.96.223')"}

Create a new filter /etc/fail2ban/filter.d/owncloud.conf with the following content :

/etc/fail2ban/filter.d/owncloud.conf
[Definition]
failregex={"reqId":".*",.*,"message":"Login failed: '.*' \(Remote IP: '<HOST>'\)".*}
ignoreregex =

Modify the jail.local file to add the [owncloud] jail.

/etc/fail2ban/jail.local
[owncloud]
enabled = true
port = http,https
filter = owncloud
logpath = /var/www/cloud.sammy.fr/owncloud/data/owncloud.log
maxretry = 3

Monitor Shaarli logs

Create a new filter /etc/fail2ban/filter.d/shaarli.conf with the following content :

/etc/fail2ban/filter.d/shaarli.conf
[INCLUDES]
before = common.conf
[Definition]
failregex = \s-\s<HOST>\s-\sLogin failed for user.*$
ignoreregex =

Modify the jail.local file to add the [shaarli] jail.

/etc/fail2ban/jail.local
[shaarli]
enabled  = true
port     = https,http
filter   = shaarli
logpath  = /var/www/shaarli.sammy.fr/data/log.txt
maxretry = 3

Use sudo fail2ban-client status shaarli to see the number of failed attempts and the IP addresses banned.

Testing Fail2Ban regex

We can test a fail2ban filter with fail2ban-regex.

For instance, if we have a log in /var/log/mail.log and a filter in /etc/fail2ban/filter.d/mail.conf we can run:

fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/mail.conf