How to Protect Your SSH Server With Fail2Ban [Linux/Ubuntu]

SSH is a good tool for you to remotely access your computer/server and make changes to it as if you are in front of the computer. If you have a SSH server, we have shown you how to generate and use a public/private key so you can connect to the remote server securely, but that doesn’t mean your SSH server is safe. On the contrary, most SSH servers are vulnerable to brute force attack and if you are not paying attention, hackers could easily hack into your server and destroy/steal everything you have.

Fail2Ban is a simple, yet useful tool that can monitor your server from malicious attack and block them before they can wreak havoc.

Fail2Ban is available in the Ubuntu repository, so you can easily install with the command:

sudo apt-get install fail2ban

For Red Hat or Centos users, you can install Fail2Ban via the EPEL repository.

Once you have installed Fail2Ban, the next step is to move the configuration file to a local folder so you won’t change the main configuration file accidentally.

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

Once installed, Fail2Ban will automatically start to monitor your server for malicious attack. In most cases, the default settings are sufficient to protect your site, but if you have some custom server configuration (like different port for SSH access) or want to enable other services, here is how you can do so:

sudo nano /etc/fail2ban/jail.local

The configuration file is divided into different sections. The first one that you will come across is [DEFAULT].

[DEFAULT]
 
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1/8
bantime  = 600
maxretry = 3
 
# "backend" specifies the backend used to get files modification. Available
# options are "gamin", "polling" and "auto".
# yoh: For some reason Debian shipped python-gamin didn't work as expected
#      This issue left ToDo, so polling is default backend for now
backend = auto
 
#
# Destination email address used solely for the interpolations in
# jail.{conf,local} configuration files.
destemail = root@localhost

The few parameters that you need to take note here is ignoreip, bantime and maxretry.

  • ignoreip – this is the place where you whitelist the IP that you don’t want to block. The default is the localhost (127.0.0.1/8). You can add additional IPs to the field, separating each IP with a space.
  • bantime – this is the amount of time in seconds to block the IP from accessing your server. The default is 10 minutes (600 seconds)
  • maxretry -this is the number of failed login attempt before the IP is blocked.

There is also the destemail field where you can specify an email address for it to notify where a malicious attack is detected. One thing to note is that this will work only if you have a mail server installed.

The next section is the “Actions”.

# ACTIONS
#
 
# 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
 
# email action. Since 0.8.1 upstream fail2ban uses sendmail
# MTA for the mailing. Change mta configuration parameter to mail
# if you want to revert to conventional 'mail'.
mta = sendmail
 
# Default protocol
protocol = tcp
 
# Specify chain where jumps would need to be added in iptables-* actions
chain = INPUT
 
#
# Action shortcuts. To be used to define action parameter
 
# The simplest action to take: ban only
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
 
# ban & send an e-mail with whois report to the destemail.
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
              %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
 
# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
               %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
 
# Choose default action.  To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_)s

Most of the settings here can be left default unless you want to change the banaction and protocol. The default “banaction” is via the IPTable. You can get it to use the multi-port setting or create a new IpTable for this. The default value for the “protocol” is tcp, but you can change it to udp , depending on which connection you are using.

The last part of the “Jail” section where you can configure Fail2Ban to monitor your Apache server, FTP server, mail server and DNS server.

[ssh]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 6

In most cases, you just have to change the “enabled = false” setting to “enabled = true” and it will be activated for that service. If you are not using the usual port 20 for SSH, you can also change the port number in the setting above.

Once you are done with the configuration, press “Ctrl + o” to save and “ctrl + x” to exit.

Lastly, restart the Fail2Ban service with the command:

sudo service fail2ban restart

What other ways do you use to protect your SSH server?