Linux security: Protect your systems with fail2ban
Security, for system administrators, is an ongoing struggle because you must secure your systems enough to protect them from unwanted attacks but not so much that user productivity is hindered. It's a difficult balance to maintain. There are always complaints of "too much" security, but when a system is compromised, the complaints range from, "There wasn't enough security" to "Why didn't you use better security controls?" The struggle is real. There are controls you can put into place that are both effective against intruder attack and yet stealthy enough to allow users to operate in a generally unfettered manner. Fail2ban is the answer to protect services from brute force and other automated attacks.
Note: Fail2ban can only be used to protect services that require username/password authentication. For example, you can't protect ping with fail2ban.
In this article, I demonstrate how to protect the SSH daemon (SSHD) from a brute force attack. You can set up filters, as fail2ban
calls them, to protect almost every listening service on your system.
Installation and initial setup
Fortunately, there is a ready-to-install package for fail2ban
that includes all dependencies, if any, for your system.
$ sudo dnf -y install fail2ban
Enable and start fail2ban
.
$ sudo systemctl enable fail2ban
$ sudo systemctl start fail2ban
Unless you have some sort of syntax problem in your fail2ban
configuration, you won't see any standard output messages.
Now to configure a few basic things in fail2ban
to protect the system without it interfering with itself. Copy the /etc/fail2ban/jail.conf
file to /etc/fail2ban/jail.local
. The jail.local
file is the configuration file of interest for us.
$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Open /etc/fail2van/jail.local
in your favorite editor and make the following changes or check to be sure these few parameters are set. Look for the setting ignoreip
and add all IP addresses to this line that must have access without the possibility of a lockout. By default, you should add the loopback address, and all IP addresses local to the protected system.
ignoreip = 127.0.0.1/8 192.168.1.10 192.168.1.20
You can also add entire networks of IP addresses, but this takes away much of the protection that you wish to engage fail2ban
for. Keep it simple and local for now. Save the jail.local
file and restart the fail2ban
service.
$ sudo systemctl restart fail2ban
You must restart fail2ban
every time you make a configuration change.
Setting up a filtered service
A fresh install of fail2ban
doesn't really do much for you. You have to set up so-called filters for any service that you want to protect. Almost every Linux system must be accessible by SSH. There are some circumstances where you would most certainly stop and disable SSHD to better secure your system, but I assume that every Linux system allows SSH connections.
Passwords, as everyone knows, are not a good security solution. However, it is often the standard by which we live. So, if user or administrative access is limited to SSH, then you should take steps to protect it. Using fail2ban
to "watch" SSHD for failed access attempts with subsequent banning is a good start.
Note: Before implementing any security control that might hinder a user's access to a system, inform the users that this new control might lock them out of a system for ten minutes (or however long you decide) if their failed login attempts exceed your threshold setting.
To set up filtered services, you must create a corresponding "jail" file under the /etc/fail2ban/jail.d
directory. For SSHD, create a new file named sshd.local
and enter service filtering instructions into it.
[sshd]
enabled = true
port = ssh
action = iptables-multiport
logpath = /var/log/secure
maxretry = 3
bantime = 600
Create the [sshd] heading and enter the setting you see above as a starting place. Most of the settings are self-explanatory. For the two that might not be intuitively obvious, the "action" setting describes the action you want fail2ban
to take in the case of a violation. For us, fail2ban
uses iptables
to ban the IP address of the offending system for a "bantime" of 600 seconds (10 minutes).
You can, of course, change any of these settings to meet your needs. Ten minutes seems to be long enough to cause a bot or script to "move on" to less secure hosts. However, ten minutes isn't so long as to alienate users who mistype their passwords more than three times.
Once you're satisfied with the settings, restart the fail2ban
service.
What banning looks like
On the protected system (192.168.1.83), tail
the /var/log/fail2ban.log
to see any current ban actions.
2020-05-15 09:12:06,722 fail2ban.filter [25417]: INFO [sshd] Found 192.168.1.69 - 2020-05-15 09:12:06
2020-05-15 09:12:07,018 fail2ban.filter [25417]: INFO [sshd] Found 192.168.1.69 - 2020-05-15 09:12:07
2020-05-15 09:12:07,286 fail2ban.actions [25417]: NOTICE [sshd] Ban 192.168.1.69
2020-05-15 09:22:08,931 fail2ban.actions [25417]: NOTICE [sshd] Unban 192.168.1.69
You can see that the IP address 192.168.1.69 was banned at 09:12 and unbanned ten minutes later at 09:22.
On the remote system, 192.168.1.69, a ban action looks like the following:
$ ssh 192.168.1.83
khess@192.168.1.83's password:
Permission denied, please try again.
khess@192.168.1.83's password:
Permission denied, please try again.
khess@192.168.1.83's password:
Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
$ ssh 192.168.1.83
ssh: connect to host 192.168.1.83 port 22: Connection refused
You can see that I entered my password incorrectly three times before being banned. The banned user, unless explicitly informed, won't know why they can no longer reach the target system. The fail2ban
filter performs a silent ban action. It gives no explanation to the remote user, nor is the user notified when the ban is lifted.
Unbanning a system
It will inevitably happen that a system gets banned that needs to be quickly unbanned. In other words, you can't or don't want to wait for the ban period to expire. The following command will immediately unban a system.
$ sudo fail2ban-client set sshd unbanip 192.168.1.69
You don't need to restart the fail2ban daemon after issuing this command.
Wrap up
That's basically how fail2ban
works. You set up a filter, and when conditions are met, then the remote system is banned. You can ban for longer periods of time, and you can set up multiple filters to protect your system. Remember that fail2ban
is a single solution and does not secure your system from other vulnerabilities. A layered, multi-faceted approach to security is the strategy you want to pursue. No single solution provides enough security.
You can find examples of other filters and some advanced fail2ban
implementations described at fail2ban.org.
[ Want to learn more about security? Check out the IT security and compliance checklist. ]
![Author’s photo](/sysadmin/sites/default/files/styles/user_picture_square/public/pictures/2019-07/Ken_Hess.jpg?itok=4v5vXdjC)
Ken Hess
Ken has used Red Hat Linux since 1996 and has written ebooks, whitepapers, actual books, thousands of exam review questions, and hundreds of articles on open source and other topics. Ken also has 20+ years of experience as an enterprise sysadmin with Unix, Linux, Windows, and Virtualization. More about me