Skip to main content

Jailing unwanted bots with Fail2Ban and custom filters

Submitted by daniel on
Image (node)
Image
Fail 2 Ban

One challenge of hosting a website online 24 hours a day 7 days a week, 365 days a year, is keeping it secure. 

I have been hosting websites for over 20 years now. One thing I have noticed, is the more successful your site is, the more attention you are likely to receive from others with nefarious intents. In fact I would even go so far as to say there is a correlation between genuine website visitors and nefarious ones. 

Sometimes if an IP or end point is being a nuisance, the easiest thing to do is to restrict access from this address.  e.g. In Drupal there is a core module called Ban that is designed with this sole purpose. However, hackers often work from a whole array of IP addresses. No sooner as you block one IP address, another one pops up. This then becomes a losing battle trying go block a single IP address. 

It is also worth mentioning, that banning IP addresses on a permanent basis is not healthy for the internet either, as it could likely stop some genuine traffic to your site at some point. You probably need a more sophisticated tool to tackle this problem.

One tools that can help us here is Fail2an. Fail2Ban has been around since 2002 that often comes preinstalled on many Web Servers. From the wiki page:

Fail2ban is an intrusion prevention software framework. Written in the Python programming language, it is designed to prevent brute-force attacks.[2] It is able to run on POSIX systems that have an interface to a packet-control system or firewall installed locally, such as iptables or TCP Wrapper.[3]

Here is a screenshot from Plesk Control Panel that show support for Fail2Ban. 

Image
Plesk Fail2Ban

So in this example we can see we have control the following:

  1. How long IP address bans are limited
  2. Time interval to measure attacked
  3. Number of retries.

Jails

Fail2Ban has the concept of Jails. Here we can see some of the default Jails in Plesk

Image
Jails - plesk - fail2ban

Fail2Ban ships with a number of Jails, that you can choose to enable or disable depending on you requirements. However, you can also add custom Jails to help beef up your sites security.

You can also add a custom jail:

Custom jails provide an additional layer of security, allowing you to create tailored filters and actions for specific applications or services. This article will explore 20 example configurations for custom jails, with example commands and configuration settings to help you get started.

Jails are listed in /etc/fail2ban/jail.d/ eg. in plesk.conf we have the following:

[plesk-wordpress]

action   = iptables-multiport[name="plesk-wordpress", port="http,https,7080,7081"]
filter   = plesk-wordpress
logpath  = /var/www/vhosts/system/*/logs/*access*log
           /var/log/httpd/*access_log

.....

Filters

As well as  jails you also have filters. Here is an example of a custom filter for wordpress located  in /etc/fail2ban/filter.d/plesk-wordpress.conf. The main part is the regular expression.
 

# Fail2Ban filter for wordpress authentication failures

[Definition]

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#

# Note: wp-login will return a 200 code on failed login and a 302 on success
failregex = ^<HOST>.* "POST .*/wp-login.php([/\?#\\].*)? HTTP/.*" 200

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#

ignoreregex =

Custom Filters

Let's have a look at creating a custom filter.

Image
error log

Here we can see on the server log we are getting lots of 404 errors for paths that do not actually exist on the site. This is adding an unwanted load on the server that is likely to slow down the site.

To familiarise yourself with fail2ban's use of regular expression, see https://www.regextester.com/94338

With the following regex , I can target this path. I can test the regex with fail2ban-regex command e.g.

fail2ban-regex /var/www/vhosts/mydomain/logs/access_ssl_log "^<HOST> .* /event-created.* 4\d\d .*$"

This will output something like:


Running tests
=============

Use   failregex line : ^<HOST> .* /event-created.* 4\d\d .*$
Use         log file : /var/www/vhosts/mydomain.x/logs/access_ssl_log
Use         encoding : UTF-8


Results
=======

Failregex: 36 total
|-  #) [# of hits] regular expression
|   1) [36] ^<HOST> .* /event-created.* 4\d\d .*$
`-

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [3182] Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
`-

Lines: 3182 lines, 0 ignored, 36 matched, 3146 missed
[processed in 2.46 sec]

We want our regex to return matching log entries. This implies that it is working.

Next we can bundle this regex into a custom filter and create a new Jail.

e.g. in /etc/fail2ban/filter.d create a file e.g. 

# Fail2Ban filter for 404 errors on /event-created path

[Definition]

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#

failregex = ^<HOST> .* /event-created.* 4\d\d .*$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#

ignoreregex =

We can test this newly created filter with the following command. Hopefully it will generate the same or similar

fail2ban-regex /var/www/vhosts/mydomain/logs/access_ssl_log /etc/fail2ban/filter.d/plesk-404.conf 

We can also create a .local file with some additional specific settings. Note this also filter and logpath keys as in the first Wordpress example.

[plesk-404]
enabled = true
filter = app404
port = http,https
logpath = %(access_ssl_log)s
bantime = 3600
findtime = 60
maxretry = 10

In fact, some control panels actually have a UI to help with this. e.g.

Image
filter local settings

Summary

Hopefully this has given you a quick overview of fail2ban and how you can write custom filters to target and limit unwanted web traffic. For any successful website, chances are as a webmaster you could benefit from some of its features. Furthermore, fail2ban can easily be extended with custom filters and jails that can contribute to improving web performance and also reduce your  chances of your website being compromised in some way.

More reading

https://fail2ban.readthedocs.io/en/latest/filters.html
 

Add new comment

Filtered HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.