protect public ssh with Fail2Ban
Servers do not exist in isolation, and those servers with only the most basic SSH configuration can be vulnerable to brute force attacks. fail2ban provides a way to automatically protect the server from malicious signs. The program works by scanning through log files and reacting to offending actions such as repeated failed login attempts.
Step One—Install Fail2Ban
Because fail2ban is not available from CentOS, we should start by downloading the EPEL repository:
rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
Follow up by installing fail2ban:
yum install fail2ban
Step Two—Copy the Configuration File
The default fail2ban configuration file is location at /etc/fail2ban/jail.conf. The configuration work should not be done in that file, however, and we should instead make a local copy of it.
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
After the file is copied, you can make all of your changes within the new jail.local file. Many of possible services that may need protection are in the file already. Each is located in its own section, configured and turned off.
Step Three—Configure defaults in Jail.Local
Open up the the new fail2ban configuration file:
The first section of defaults covers the basic rules that fail2ban will follow. If you want to set up more nuanced protection for your virtual private server, you can customize the details in each section.
You can see the default section below.
[DEFAULT] # "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not # ban a host which matches an address in this list. Several addresses can be # defined using space separator. ignoreip = 127.0.0.1 # "bantime" is the number of seconds that a host is banned. bantime = 3600 # A host is banned if it has generated "maxretry" during the last "findtime" # seconds. findtime = 600 # "maxretry" is the number of failures before a host get banned. maxretry = 3
Write your personal IP address into the ignoreip line. You can separate each address with a space. IgnoreIP allows you white list certain IP addresses and make sure that they are not locked out from your VPS. Including your address will guarantee that you do not accidentally ban yourself from your own virtual private server.
The next step is to decide on a bantime, the number of seconds that a host would be blocked from the server if they are found to be in violation of any of the rules. This is especially useful in the case of bots, that once banned, will simply move on to the next target. The default is set for 10 minutes—you may raise this to an hour (or higher) if you like.
Maxretry is the amount of incorrect login attempts that a host may have before they get banned for the length of the ban time.
Findtime refers to the amount of time that a host has to log in. The default setting is 10 minutes; this means that if a host attempts, and fails, to log in more than the maxretry number of times in the designated 10 minutes, they will be banned.
Step Four (Optional)—Configure the ssh-iptables Section in Jail.Local
The SSH details section is just a little further down in the config, and it is already set up and turned on. Although you should not be required to make to make any changes within this section, you can find the details about each line below.
[ssh-iptables] enabled = true filter = sshd action = iptables[name=SSH, port=ssh, protocol=tcp] sendmail-whois[name=SSH, dest=root, email@example.com] logpath = /var/log/secure maxretry = 5
Enabled simply refers to the fact that SSH protection is on. You can turn it off with the word "false".
The filter, set by default to sshd, refers to the config file containing the rules that fail2banuses to find matches. The name is a shortened version of the file extension. For example, sshd refers to the /etc/fail2ban/filter.d/sshd.conf.
Action describes the steps that fail2ban will take to ban a matching IP address. Just like the filter entry, each action refers to a file within the action.d directory. The default ban action, "iptables" can be found at /etc/fail2ban/action.d/iptables.conf .
In the "iptables" details, you can customize fail2ban further. For example, if you are using a non-standard port, you can change the port number within the brackets to match, making the line look more like this:
eg. iptables[name=SSH, port=30000, protocol=tcp]
You can change the protocol from TCP to UDP in this line as well, depending on which one you want fail2ban to monitor.
If you have a mail server set up on your virtual private server, Fail2Ban can email you when it bans an IP address. In the default case, the sendmail-whois refers to the actions located at /etc/fail2ban/action.d/sendmail-whois.conf.
log path refers to the log location that fail2ban will track.
The max retry line within the SSH section has the same definition as the default option. However, if you have enabled multiple services and want to have specific values for each one, you can set the new max retry amount for SSH here.
Step Five—Restart Fail2Ban
After making any changes to the fail2ban config, always be sure to restart Fail2Ban:
sudo service fail2ban restart
You can see the rules that fail2ban puts in effect within the IP table:
While connecting to your server through SSH can be very secure, the SSH daemon itself is a service that must be exposed to the Internet to function properly. This comes with some inherent risk and offers a vector of attack for would-be assailants.
Any service that is exposed to the network is a potential target in this way. If you pay attention to application logs for these services, you will often see repeated, systematic login attempts that represent brute-force attacks by users and bots alike.
A service called Fail2ban can mitigate this problem by creating rules that automatically alter your iptables firewall configuration based on a predefined number of unsuccessful login attempts. This will allow your server to respond to illegitimate access attempts without intervention from you.
In this guide, we'll cover how to install and use Fail2ban on a CentOS 7 server.
Install Fail2ban on CentOS 7
While Fail2ban is not available in the official CentOS package repository, it is packaged for the EPEL project. EPEL, standing for Extra Packages for Enterprise Linux, can be installed with a release package that is available from CentOS:
You will be prompted to continue---press y, followed by Enter:
Transaction Summary ============================================================================ Install 1 Package Total download size: 14 k Installed size: 24 k Is this ok [y/d/N]: y
Now we should be able to install the fail2ban package:
Again, press y and Enter when prompted to continue.
Once the installation has finished, use systemctl to enable the fail2ban service:
Configure Local Settings
The Fail2ban service keeps its configuration files in the /etc/fail2ban directory. There, you can find a file with default values called jail.conf. Since this file may be overwritten by package upgrades, we shouldn't edit it in-place. Instead, we'll write a new file called jail.local. Any values defined in jail.local will override those in jail.conf.
jail.conf contains a [DEFAULT] section, followed by sections for individual services. jail.localmay override any of these values. Additionally, files in /etc/fail2ban/jail.d/ can be used to override settings in both of these files. Files are applied in the following order:
Any file may contain a [DEFAULT] section, executed first, and may also contain sections for individual jails. The last vavalue set for a given parameter takes precedence.
Let's begin by writing a very simple version of jail.local. Open a new file using nano (or your editor of choice):
Paste the following:
[DEFAULT] # Ban hosts for one hour: bantime = 3600 # Override /etc/fail2ban/jail.d/00-firewalld.conf: banaction = iptables-multiport [sshd] enabled = true
This overrides three settings: It sets a new default bantime for all services, makes sure we're using iptables for firewall configuration, and enables the sshd jail.
Exit and save the new file (in nano, press Ctrl-X to exit, y to save, and Enter to confirm the filename). Now we can restart the fail2ban service using systemctl:
The systemctl command should finish without any output. In order to check that the service is running, we can use fail2ban-client:
Status |- Number of jail: 1 `- Jail list: sshd
You can also get more detailed information about a specific jail:
Explore Available Settings
The version of jail.local we defined above is a good start, but you may want to adjust a number of other settings. Open jail.conf, and we'll examine some of the defaults. If you decide to change any of these values, remember that they should be copied to the appropriate section of jail.local and adjusted there, rather than modified in-place.
Default Settings for All Jails
First, scroll through the [DEFAULT] section.
ignoreip = 127.0.0.1/8
You can adjust the source addresses that Fail2ban ignores by adding a value to the ignoreip parameter. Currently, it is configured not to ban any traffic coming from the local machine. You can include additional addresses to ignore by appending them to the end of the parameter, separated by a space.
bantime = 600
The bantime parameter sets the length of time that a client will be banned when they have failed to authenticate correctly. This is measured in seconds. By default, this is set to 600 seconds, or 10 minutes.
findtime = 600 maxretry = 3
The next two parameters that you want to pay attention to are findtime and maxretry. These work together to establish the conditions under which a client should be banned.
The maxretry variable sets the number of tries a client has to authenticate within a window of time defined by findtime, before being banned. With the default settings, Fail2ban will ban a client that unsuccessfully attempts to log in 3 times within a 10 minute window.
destemail = root@localhost sendername = Fail2Ban mta = sendmail
If you wish to configure email alerts, you may need to override the destemail, sendername, and mtasettings. The destemail parameter sets the email address that should receive ban messages. The sendername sets the value of the "From" field in the email. The mta parameter configures what mail service will be used to send mail.
action = $(action_)s
This parameter configures the action that Fail2ban takes when it wants to institute a ban. The value action_ is defined in the file shortly before this parameter. The default action is to simply configure the firewall to reject traffic from the offending host until the ban time elapses.
If you would like to configure email alerts, you can override this value from action_ to action_mw. If you want the email to include the relevant log lines, you can change it to action_mwl. You'll want to make sure you have the appropriate mail settings configured if you choose to use mail alerts.
Settings for Individual Jails
After [DEFAULT], we'll encounter sections configuring individual jails for different services. These will typically include a port to be banned and a logpath to monitor for malicious access attempts. For example, the SSH jail we already enabled in jail.local has the following settings:
[sshd] port = ssh logpath = %(sshd_log)s
In this case, ssh is a pre-defined variable for the standard SSH port, and %(sshd_log)s uses a value defined elsewhere in Fail2ban's standard configuration (this helps keep jail.conf portable between different operating systems).
Another setting you may encounter is the filter that will be used to decide whether a line in a log indicates a failed authentication.
The filter value is actually a reference to a file located in the /etc/fail2ban/filter.d directory, with its .conf extension removed. This file contains the regular expressions that determine whether a line in the log is bad. We won't be covering this file in-depth in this guide, because it is fairly complex and the predefined settings match appropriate lines well.
However, you can see what kind of filters are available by looking into that directory:
If you see a file that looks to be related to a service you are using, you should open it with a text editor. Most of the files are fairly well commented and you should be able to tell what type of condition the script was designed to guard against. Most of these filters have appropriate (disabled) sections in jail.confthat we can enable in jail.local if desired.
For instance, pretend that we are serving a website using Nginx and realize that a password-protected portion of our site is getting slammed with login attempts. We can tell Fail2ban to use the nginx-http-auth.conf file to check for this condition within the /var/log/nginx/error.log file.
This is actually already set up in a section called [nginx-http-auth] in our /etc/fail2ban/jail.conf file. We would just need to add an enabled parameter for the nginx-http-auth jail to jail.local:
[DEFAULT] # Ban hosts for one hour: bantime = 3600 # Override /etc/fail2ban/jail.d/00-firewalld.conf: banaction = iptables-multiport [sshd] enabled = true [nginx-http-auth] enabled = true
And restart the fail2ban service:
Monitor Fail2ban Logs and Firewall Configuration
It's important to know that a service like Fail2ban is working as-intended. Start by using systemctl to check the status of the service:
If something seems amiss here, you can troubleshoot by checking logs for the fail2ban unit since the last boot:
Next, use fail2ban-client to query the overall status of fail2ban-server, or any individual jail:
Follow Fail2ban's log for a record of recent actions (press Ctrl-C to exit):
List the current rules configured for iptables:
Show iptables rules in a format that reflects the commands necessary to enable each rule:
You should now be able to configure some basic banning policies for your services. Fail2ban is very easy to set up, and is a great way to protect any kind of service that uses authentication.
If you want to learn more about how Fail2ban works, you can check out our tutorial on how fail2ban rules and files work.
the above digital ocean explains they couldn't get this working with firewalld. however this link seems to explain leaving the /etc/fail2ban/jail.d/00-firewalld.conf and the jail.local with no comments to disable firewalld