Configuring Fail2Ban To Protect Services

There are a number of automated banning tools that check for bad behavior but I like fail2ban as it’s flexible and extensible. Configuring fail2ban requires adjustment and testing but can be comprehensive. Certainly sshguard and denyhosts are solid options and if you’re only looking for something to monitor ssh, those are a great way to go.

installing configuring fail2ban
some of the wonderful ssh tools available to bad guys

Note: This a guide to one security tool. You are responsible for securing and exposing a service to the internet. I would not put a fresh box up with ssh open on the internet with only fail2ban installed, for example. (You might also want to harden the service directly.)

Configuring Fail2Ban: Installation

I lean towards fail2ban as it comes packaged with a number of filters and an extensible regex system that lets me monitor and block on any service I want. It can even work as a (bad, jury-rigged) web application firewall depending on your risk needs.

That said, fail2ban requires a little more time to set up properly than some of the other options. In this example, I’m going to be using CentOS, but much of this should work anywhere.

First, we install:

# yum install fail2ban

Configuring Fail2Ban: Configuration

This puts the configuration information under the /etc/fail2ban folder, and we’re going to put our relevant configuration data into /etc/fail2ban/jail.local. Version upgrades should not overwrite the jail.local file. Now, we’re going to go over the [DEFAULT] section, which establishes what the defaults are for any fail2ban service, and which can be overwritten in the service-specific section.

bantime = 86400
findtime = 3600
maxretry = 3
ignoreip =
banaction = iptables-multiport
banaction_allports = iptables-allports
backend = pyinotify

bantime: the length of time to ban an IP address. In our example, we’re banning IP addresses for 24 hours.
findtime: this is the length of time that fail2ban will look over for failures. This is one hour, so the threshold number of failures have to happen in a one our time frame.
maxretry: the number of failures that will trigger fail2ban to action.
ignoreip: a space-separated whitelist of IP addresses that fail2ban will ignore. I’ve put Google’s DNS servers in here as an example.
banaction and banaction_allports: the action that fail2ban will take on trigger threshold. These values represent .conf files in /etc/fail2ban/action.d, so you can see what they do (or write your own!) if you like. This is a Linux system with iptables, so we use the canned iptables actions.
backend: This tells fail2ban to use pyinotify to watch log files, which it prefers. Also available: polling or gamin. If you don’t know what your system has, just start by setting it to auto.

These are just some starter defaults; everything is adjustable on a per-service basis.


Configuring Fail2Ban: SSH

Here’s an example for the ssh service:

enabled = true
port = ssh,sftp
logpath = /var/log/secure
filter = sshd

[]: The bit in [] is just the label for the service. You can name it whatever you like. So, we’re naming it ssh.

enabled: A bool value enabling the filter.
port: The name of a (known) service or raw port numbers, separated by commas.
logpath: The location of the relevant log file that fail2ban should be checking. Also: this can also accept wildcards (/var/log/*.log) or space-separated values.
filter: This tells fail2ban to use the sshd filter, which is a canned filter representing a .conf file in /etc/fail2ban/filter.d. fail2ban includes canned filters for a number of common services and you should be taking advantage of that.

Additionally, you should feel free to adjust any of the options from the [DEFAULT] section on a per-service basis as needed.

Configuring Fail2Ban: Customization

What I really like about fail2ban is that you’re free to create your own filter files using a relatively simple regex syntax. If you have no experience with regex, load up a site like this one and select Python. It won’t be perfect, since fail2ban has some custom tags like <HOST>, but it should help. (I don’t know anyone that does regex regularly enough that they don’t need a reference of some kind. If you don’t, you are probably a wizard.)

The relevant bits of the /etc/fail2ban/filters.d/sshd-ddos.conf file:

failregex = ^%(__prefix_line)sDid not receive identification string from <HOST>\s*$

This lets you set what failure conditions are (what fail2ban should consider in its threshold) using a regex string. Combined with the logpath above, you’re free to test and check everything before it goes into production using the handy included fail2ban-regex command using the format fail2ban-regex <log> <regex>:

# fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd-ddos.conf

Running tests

Use failregex filter file : sshd-ddos, basedir: /etc/fail2ban
Use log file : /var/log/secure
Use encoding : UTF-8


Failregex: 0 total

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
| [47] (?:DAY )?MON Day 24hour:Minute:Second(?:\.Microseconds)?(?: Year)?

Lines: 47 lines, 0 ignored, 0 matched, 47 missed
[processed in 0.01 sec]

Missed line(s): too many to print. Use --print-all-missed to print all 47 lines

Failregex 0 means that it found no matching lines for failure, which is good. This is where you’d want to intentionally fail some login attempts to see if the failregex number goes up in testing, etc.

Once comfortable that you’re only matching things in your log that you want to (the –print-all-matched, –print-all-missed, and –print-all-ignored switches are a huge help), you can bring it up live by reloading your fail2ban config or restarting the service.

Further, once live and public-facing, you should see fail2ban activity in your log files immediately, due to scanners. This is in /var/log/messages on CentOS, but may be in a custom fail2ban.log file depending on your OS/distro.

Configuring Fail2Ban: Conclusion

Finally, once you have a working fail2ban installation for some canned services, it’s straightforward to build custom rules to watch for bad behavior on web services or applications.

One thought on “Configuring Fail2Ban To Protect Services”

Leave a Reply

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