Securing SSH access with Fail2ban and GeoIP filtering

Any service that is exposed to the network is a potential target, and SSH being so widely deployed across the internet means that it represents a very predictable attack surface or attack vector through which people can try to gain access.

If you review the logs for your SSH service running on any widely trafficked server, you will often see repeated, systematic login attempts that represent brute force attacks by users and bots alike.

tail /var/log/auth.log

These attacks can be mitigated through some basic steps:

  • Disabling password authentication in favor of SSH keys (sshd_config):
    PasswordAuthentication no
  • As well as changing the standard port (sshd_config)
    Port 48513

Limiting attempts to reduce brute force attacks and restricting IP ranges or geographical provenance is another important step. I usually use CSF, a web application firewall (WAF) that ensures diverse security aspect.

However in this article, we will see some basic essential tools in Linux systems: Fail2ban & GeoIP filtring.

Fail2ban

Fail2Ban

Fail2ban is an Intrusion Prevention System (IPS) that scans log files like /var/log/auth.log and bans IP addresses conducting too many failed login attempts. It does this by updating system firewall rules to reject new connections from those IP addresses, for a configurable amount of time.

apt/yum install fail2ban

Fail2Ban comes out-of-the-box ready to read many standard log files, such as those for sshd and Apache, and is easily configured to read any log file of your choosing, for any error you wish.

You are also able to customize the default jail config, it is recommended to clone the default configuration to override it:

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

In which you can adjust different options such as ban time, number of failed attemps, email notifications, etc.

 
[DEFAULT]bantime = 10mfindtime = 10mmaxretry = 5

Setting up geographical limitation

To mitigate thebots and malicious connections which originate usually from countries you never connect from, restricting access attempts based on geographical location can be a valuable security measure.

We can filter using a GeoIP database:

apt install geoip-bin geoip-database # For apt-based systems

or
yum install geoip # For yum-based systems

The package will set up two new commands geolookupfor ipv4 and geolookup for ipv6.

geoiplookup 1.1.1.1

GeoIP Country Edition: AU, Australia

These are the commands we will use in our filtring script (/usr/local/bin/geoIPFiltring.sh):

#!/bin/bash# based on script from http://www.axllent.org/docs/view/ssh-geoip# License: WTFPL# UPPERCASE space-separated country codes to ACCEPTALLOW_COUNTRIES="DZ TN"LOGDENY_FACILITY="authpriv.notice"if [ $# -ne 1 ]; then  echo "Usage:  `basename $0` <ip>" 1>&2  exit 0 # return true in case of config issuefiif [[ "`echo $1 | grep ':'`" != "" ]] ; then  COUNTRY=`/usr/bin/geoiplookup6 "$1" | awk -F ": " '{ print $2 }' | awk -F "," '{ print $1 }' | head -n 1`else  COUNTRY=`/usr/bin/geoiplookup "$1" | awk -F ": " '{ print $2 }' | awk -F "," '{ print $1 }' | head -n 1`fi[[ $COUNTRY = "IP Address not found" || $ALLOW_COUNTRIES =~ $COUNTRY ]] && RESPONSE="ALLOW" || RESPONSE="DENY"if [[ "$RESPONSE" == "ALLOW" ]] ; then  exit 0else  logger -p $LOGDENY_FACILITY "$RESPONSE sshd connection from $1 ($COUNTRY)"  exit 1fi

It can be tested

/usr/local/bin/geoIPFiltring.sh 1.1.1.1

Then, we need to implement our script before the service authentification. This can be done using the host-based networking ACL (hosts.allow and hosts.deny which are part of the default Linux package tcp_wrappers).

First we need to deny all the incoming connections by adding to /etc/hosts.deny.

sshd: ALL

Then, we will filter the incoming IP/TCP connection to the SSHD service by adding the following line to /etc/hosts.allow:

sshd: ALL: aclexec /usr/local/bin/ssh-filter.sh %a

The same can be done with other services such as FTP, you can deny:
vsftpd: ALL

And allow:

vsftp: ALL: aclexec /usr/local/bin/ipfilter.sh %a

 

P.S.: Note that the legacy command-line geoiplookup is no longer maintained with fresh data from MaxMind. You may consider other alternatives which uses the current v2 format such as:

https://github.com/axllent/goiplookup

 


I may add later to this post other methods and softwares such as CSF.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *