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
You can check all the blocked IPs by running the command:
fail2ban-client status sshd
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.