Keeping secure configurations is obviously needed but using extra technologies and tools to prevent attacks like brute-forcing is much needed at present.

You may worry to monitor the server logs and take required action according to the logs by yourself. But by using tools like fail2ban you can leave all of this to the server itself to take predefined action according to the predefined logs entries and rules. 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 itself do the work by responding to possible break-in attempts without any intervention from you.

In this guide, i will cover how to install and configure fail2ban on a Centos7 server.

INSTALL fail2ban

As fail2ban is not available in official Centos package repository, it can be installed after installing epel release package.(Extra Packages for Enterprise Linux)

sudo yum install epel-release

Now we should be able to install fail2ban package.

sudo yum install fail2ban

After the installation is finished, use systemctl command to enable the fail2ban service.

sudo systemctl enable fail2ban

Configure fail2ban

The default location of the configuration files of fail2ban is /etc/fail2ban/.

There you can find a file with some default values called jail.conf , we shouldn’t edit this in-place.

Let’s begin by writing a simple version of jail.local . Use vim or nano to open a new file.

sudo vim /etc/fail2ban/jail.local

Paste the following:

[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 = 1200 

banaction = iptables-multiport    

# "maxretry" is the number of failures before a host get banned. 
maxretry = 4  

[ssh-iptables] 
enabled = true 
filter = sshd 
action = iptables[name=SSH, port=ssh, protocol=tcp] 
logpath = /var/log/secure  
                                                                                                  

This file will enable the sshd jail and makes sure you are using iptables for firewall configuration.

We can restart the fail2ban service using systemctl.

sudo systemctl restart fail2ban

In order to check that service is running as expected , use below command:

sudo fail2ban-client status

You can also get more details about specific jail:

sudo fail2ban-client status sshd

 

OTHER AVAILABLE SETTINGS

A number of settings can be adjusted by editing jail.conf. It will be better to not touch this file and modify our settings per individual jails through jail.local file.

Simply append any more jails in the jail.local file similar to how we did above for sshd.

To edit some common or specific settings for jails , open jail.conf

sudo vim /etc/fail2ban/jail.conf

We can edit the ” [DEFAULT]  ” section in this file for default settings to be enabled for all the jails.

Below the ” [DEFAULT]  ” section, you can find settings for individual jails and can be adjusted as per own need.

FILTERS

Another setting you may encounter is filter that actually decides whether or not  a line in log file indicates a failed authentication.

The filter value in jail.conf or jail.local is reference to a file located in the directory /etc/fail2ban/filter.d/ . This file contains the regular expressions that determine whether or not a line in the log is bad.

You can see what kind of filters are available by looking into that directory:

ls /etc/fail2ban/filter.d/

If you see a file that looks to be related to a service you are using, you should open it with a text editor. As we are enabling sshd jail here , lets open it’s filter file.

sudo vim /etc/fail2ban/filter.d/sshd.conf                                                                                                                                                                             
# Fail2Ban filter for openssh 
# 
# If you want to protect OpenSSH from being bruteforced by password                                                                  
# authentication then get public key authentication working before disabling
# PasswordAuthentication in sshd_config. 
# 
#
# "Connection from <HOST> port \d+" requires LogLevel VERBOSE in sshd_config 
#   
[INCLUDES]
# Read common prefixes. If any customizations available -- read them from
# common.local 
before = common.conf 

[Definition]
_daemon = sshd

failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error|failed) for .* from <HOST>( via \S+)?\s*$ 
            ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$                         
            ^%(__prefix_line)sFailed \S+ for (?P<cond_inv>invalid user )?(?P<user>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)) from <HOST>(?: port \d+)?(?: ssh\d*)?(?(cond_user):|(?:(?:(?! from ).)*)$) 
            ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$ 
            ^%(__prefix_line)s[iI](?:llegal|nvalid) user .*? from <HOST>(?: port \d+)?\s*$ 
            ^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$ 
            ^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$ 
            ^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$ 
            ^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$ 
            ^%(__prefix_line)s(?:error: )?Received disconnect from <HOST>: 3: .*: Auth fail(?: \[preauth\])?$ 
            ^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$ 
            ^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$ 
            ^(?P<__prefix>%(__prefix_line)s)User .+ not allowed because account is locked<SKIPLINES>(?P=__prefix)(?:error: )?Received disconnect from <HOST>: 11: .+ \[preauth\]$ 
            ^(?P<__prefix>%(__prefix_line)s)Disconnecting: Too many authentication failures for .+? \[preauth\]<SKIPLINES>(?P=__prefix)(?:error: )?Connection closed by <HOST> \[preauth\]$ 
            ^(?P<__prefix>%(__prefix_line)s)Connection from <HOST> port \d+(?: on \S+ port \d+)?<SKIPLINES>(?P=__prefix)Disconnecting: Too many authentication failures for .+? \[preauth\]$ 
            ^%(__prefix_line)s(error: )?maximum authentication attempts exceeded for .* from <HOST>(?: port \d*)?(?: ssh\d*)? \[preauth\]$ 
            ^%(__prefix_line)spam_unix\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=\S*\s*rhost=<HOST>\s.*$ 

ignoreregex =        

[Init]

# "maxlines" is number of log lines to buffer for multi-line regex searches 
maxlines = 200 

journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd 

# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black 

As you can see above , this file contains the failregex which decides whether any line in the log file is bad or not. We can also append some more failregex as per need but it has to be in correct format which can take time to understand.

A very common line in our ssh log file that we find these days is “POSSIBLE BREAK-IN ATTEMPT”. The above ssh jail may not be able to detect this line and fail to block to block the attempt when this line appears in the log file. Remember that the above line does not mean your server has been hacked, but yes someone is definitely trying to do something nasty. Thus it is very much required to add new failregex for our sshd jail.

Carefully append below line in the failregex section of /etc/fail2ban/filter.d/sshd.conf .

 ^%(__prefix_line)sreverse mapping checking getaddrinfo .* \[<HOST>\] failed - POSSIBLE BREAK-IN ATTEMPT!\s*$ 

Now restart the fail2ban service using systemctl.

sudo systemctl restart fail2ban

You can view fail2ban logs at location /var/log/fail2ban.log .

This is very simple configuration to prevent ssh brute force attack against your centos7 server.

I hope this post has been helpful to you. Now Fail2ban is ready to secure your Centos server/system against ssh brute force attacks.

Comment below any issues faced and i will try best to provide you the solution as soon as possible. Feel free to provide suggestions.

Connect with me on LinkedIn by clicking here.

2 thoughts on “Preventing brute force attacks against SSH using fail2ban

Leave a comment

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