Secure your computer using fail2ban

If you are not aware, fail2ban is a brute-force attack mitigation tool. This post will guide you to quickly install fail2ban with basic configuration. In this article I will be showing how to configure fail2ban for SSH brute-force attacks.

Let’s cut to the chase and start installing fail2ban.

For the purpose of this demonstration I shall be using Fedora 31. You should be able to find similar commands in your respective distros.

Installation

Installation is pretty straight forward similar to installing any other software in Linux. I will use the DNF package manager which is the default for Fedora now.

dnf install fail2ban -y

Configuration

In fail2ban, setup for a particular service like SSH is called as jail. Like any intruder being put into a jail, any intruder attempting to gain access to your server via SSH would be put inside “SSHD jail” and anyone trying to gain access via SFTP would be put inside “SFTP jail”. Controlling the parameters to be “eligible” to be put into these jails are handled by jail configuration file.

There are 2 configuration files in fail2ban:

  • /etc/fail2ban/jail.conf
  • /etc/fail2ban/fail2ban.conf

It is recommended not to edit these files, but to create a copy of them with ‘.local’ file extension. Once you have created the copy change the desired values in those files.

fail2ban.conf file has the configuration to control fail2ban’s behaviour. For instance you can set the log level parameters here.
jail.conf file is where you enable services (like ssh, sftp, apache) which you wish to monitor for intrusion. You also define criteria’s on when to block the IPs.

Below are the brief steps I usually follow to setup fail2ban to mitigate SSH brute-force attacks on my servers.

1. Create ‘local’ copies of config files:

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

2. Enable SSHD jail in jail.local file

First run the below command to check the active jails configured(should be none obviously):

fail2ban-client status

Since this is a fresh installation we can see that no jail has been configured.

Open the jail.conf using your favorite editor(obviously it’s vim!). Find the section where it says [sshd]. You might find 2 entries, 1 commented and the other uncommented, go to the uncommented entry which should look like this:

Change it to make it look something like this:

#
# SSH servers
#

[sshd]

# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode   = normal
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3

What did we exactly do here ?

  • enabled : This enables the SSHD jail for fail2ban to keep monitoring the SSH connections to your server.
  • maxretry : This defines how many incorrect password tries will you allow users trying to connect to your server via SSH. Beyond this, fail2ban will block them.

3. Additional Configuration

You can skip to step 4, if you want to ignore the below additional configurations but trust me you would want to know about these steps

I prefer to change few other parameters in jail.local when I setup fail2ban.

Ignoring IPs from being blocked

I have this habit of adding my own IPs to exception list so that I never get blocked by fail2ban. You might want to add your work IPs to this list so that you don’t get blocked while connecting from office in case you enter incorrect credentials multiple times. To add the the IPs that you want to exclude from monitoring, add them to the ignoreip parameter.

Uncomment and change the below line in jail.local

#ignoreip = 127.0.0.1/8 ::1

to

ignoreip = 127.0.0.1/8 ::1 192.168.1.119

Assuming that my local IP that I want to exclude from blocking is 192.168.1.119, fail2ban will not “ban” this IP no matter how many times I enter incorrect credentials. You can add any number of IPs separated by space or comma.

Changing bantime and findtime

Fail2ban gives you the ability to customize certain things like When to Ban? How long to Ban?

findtime parameter instructs fail2ban, within what duration should the “maxretry” value be checked. We had set the maxretry value(in sshd setup above) to 3, lets say we set findtime value to 60mins. So within 60mins if there are 3 incorrect attempts to login, then source IP gets added to ban list.

bantime parameter defines how long the IP should be banned, you may wish to ban the IP for a day, a week or a month. This parameter instructs fail2ban the same thing.

For example, lets say our maxretry value is 3 in SSHD configuration. You want to ban users if he enters incorrect password 3 times within a span of 10mins and block him from further attempting to try logging in for 3 days. You will change the value as below:

findtime = 10m

bantime = 76h

Enable logging via systemd journals

Fedora has a problem where unless logging is directed via systemd journald, it throws an error while starting fail2ban. To avoid this issue, you need to tell fail2ban to log via systemd journald by changing the below parameter:

backend = auto

to

backend = systemd

Tell fail2ban to use firewalld to block the IPs

I use firewalld as my firewall management tool so I tell fail2ban to use it to block the IPs by changing the below parameter

# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
banaction = iptables-multiport
banaction_allports = iptables-allports

changed to:

# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
banaction = firewallcmd-ipset
banaction_allports = firewallcmd-ipset

Verify and start fail2ban

Once we have all the changes done, we can verify our setup by running the command:

fail2ban-client -x start

fail2ban will tell us that set up in looking good.

Next step is to enable fail2ban so that it starts at boot time automatically. Then we proceed to start the fail2ban service to start monitoring all SSH connections.

Enable fail2ban so that it automatically starts at boot time

systemctl enable fail2ban.service

Start fail2ban service using the command:

systemctl start fail2ban.service

Make sure fail2ban is running fine

systemctl status fail2ban.service

Congratulations! We just enabled SSH jail to start monitoring all SSH connections to your server. You can check your ssh jail status by running the below command:

fail2ban-client status

We can see 1 jail is configured, and the service enabled is SSH

You can check all the blocked IPs by running the command:

fail2ban-client status sshd

No IPs are blocked as it is a fresh installation

You can find the jail.local file with all the configuration discussed in this article here.

Some useful commands to keep in mind

  • Check all services monitored by fail2ban: fail2ban-client status
  • Check the blocked IP List by ssh jail: fail2ban-client status sshd
  • Remove blocked IPs: fail2ban-client set sshd unbanip 192.168.143.191
  • Remove all blocked IPs: fail2ban-client unban --all

Enable Debugging

In case you stumble upon any issues, we can enable debugging to get more information.

1. Open the file: /etc/fail2ban/fail2ban.local and change the below parameter

loglevel = INFO

Change to

loglevel = DEBUG

2. Restart the service

systemctl restart fail2ban

3. Monitor the debug messages by looking at the log file which be found at: /var/log/fail2ban.log

tail -f /var/log/fail2ban.log

If you wish to see fail2ban in action, I suggest you head to the video tutorial that I created regarding fail2ban setup. You can drag the video to go directly to 06:32 to see fail2ban in action skipping all the setup which we already discussed in this article.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.