How to Allow SSH Access Based on Country

GeoIP database has records of Geographical location based on IP address. Using this database we can search for any IP belonging to which country using the Linux command line. This article will help you to allow SSH or FTP (vsftpd) access based on the user’s country. This example uses TCP wrappers to secure your services.

Advertisement

Install GeoIP and GeoIP Database

First, install GeoIP binary for Linux and their database based on your operating system. For CentOS and RedHat users GeoIP binary and database are combined in a single package.

On CentOS and RedHat:
sudo yum install GeoIP 
On Ubuntu and Debian:
sudo apt-get install geoip-bin geoip-database 

Create the SSH/FTP Filter Script

Now create a shell script that checks for all incoming connection IP addresses and searches their corresponding country using the GeoIP database and allowed only those countries whose code is defined in ALLOW_COUNTRIES variable in the script.ADVERTISEMENT

vim /usr/local/bin/ipfilter.sh 
#!/bin/bash
# License: WTFPL

# UPPERCASE space-separated country codes to ACCEPT
ALLOW_COUNTRIES="IN US"
LOGDENY_FACILITY="authpriv.notice"

if [ $# -ne 1 ]; then
  echo "Usage:  `basename $0` " 1>&2
  exit 0 # return true in case of config issue
fi

if [[ "`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
  logger -p $LOGDENY_FACILITY "$RESPONSE sshd connection from $1 ($COUNTRY)"
  exit 0
else
  logger -p $LOGDENY_FACILITY "$RESPONSE sshd connection from $1 ($COUNTRY)"
  exit 1
fi

Script srouce: https://gist.github.com/jokey2k/a74f56955124880749e7

Make this script executableADVERTISEMENT

chmod +x /usr/local/bin/ipfilter.sh 

Restrict SSH/FTP Connections

Now apply SSH and FTP restrictions using TCP wrappers. First we need to deny everyone by adding below line in /etc/hosts.deny.

/etc/hosts.deny:

sshd: ALL
vsftpd: ALL

Now edit /etc/hosts.allow and allow only those ips which are allowed by your IP filter script.ADVERTISEMENT

/etc/hosts.allow:

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

Above FTP restrictions are for vsftpd only. Also, make sure you have enabled (tcp_wrappers=YES) in your vsftpd configuration. You can also create similar rules for any other services supported by a TCP wrapper.

Testing

Finally, test your server by login in using SSH or FTP from different-2 locations and analyze the access log files. Below are some demo logs created by ipfilter.sh.

Feb 27 13:03:29 TecAdmin root: DENY sshd connection from 212.191.246.202 (PL)
Feb 27 13:34:28 TecAdmin root: DENY sshd connection from 212.181.246.202 (SE)
Feb 27 13:34:36 TecAdmin root: DENY sshd connection from 211.181.246.203 (KR)
Feb 27 13:35:00 TecAdmin root: DENY sshd connection from 221.191.146.204 (JP)
Feb 27 15:11:04 TecAdmin root: ALLOW sshd connection from 49.15.212.12 (IN)
Feb 27 15:11:09 TecAdmin root: ALLOW sshd connection from 149.15.212.12 (US)
Feb 27 15:11:22 TecAdmin root: ALLOW sshd connection from 49.15.156.123 (IN)
Feb 27 15:11:32 TecAdmin root: ALLOW sshd connection from 231.15.156.123 (IP Address not found)
Feb 27 15:14:04 TecAdmin root: DENY sshd connection from 111.15.15.123 (CN)
Feb 27 15:14:56 TecAdmin root: ALLOW sshd connection from 49.15.110.123 (IN)

In logs, you can say that all ips belonging to the US (United States) and IN (India) are allowed. Also if any IP does not match in the GeoIP database will be allowed by default. The rest of the matching other countries’ ips are denied.

Ref: https://tecadmin.net/allow-server-access-based-on-country/