Could we help you? Please click the banners. We are young and desperately need the money
In this blog post, we will explore how to enhance the security of your Debian / Ubuntu Linux server by limiting SSH access based on the geographic location of incoming connections. By leveraging GeoIP data, we can restrict access to only those countries we trust. This approach adds an extra layer of security, reducing the risk of unauthorized access from foreign IP addresses.
This tutorial is aimed at experienced Linux users and system administrators who want to improve their server's security.
First, we need to add the contrib repository to our /etc/apt/sources.list file. This is necessary to install the geoipupdate tool.
sudo nano /etc/apt/sources.list
Add contrib to the end of the lines. For example:
deb http://deb.debian.org/debian/ buster main contrib non-free
deb-src http://deb.debian.org/debian/ buster main contrib non-free
After updating the sources list, run:
sudo apt update
Next, install geoipupdate:
sudo apt install geoipupdate
To use the GeoLite2 database, you need to create a free account on the MaxMind website and obtain a free license key. Follow these steps:
Once you have your account and license key, edit the GeoIP configuration file:
sudo nano /etc/GeoIP.conf
Add your AccountID and LicenseKey:
# `AccountID` is from your MaxMind account.
AccountID 123456
# `LicenseKey` is from your MaxMind account
LicenseKey EXAMPLEMAXMINDKEY
Install mmdblookup to query the MaxMind database:
sudo apt install mmdblookup
Now, let's create a script that will use the GeoIP database to determine if an IP address is allowed to connect via SSH. Here’s the script:
<!-- Formatted and HTML-encoded complete script -->
<pre><code># UPPERCASE space-separated country codes to ACCEPT
ALLOW_COUNTRIES="CH"
GEOIP_BIN=$(which mmdblookup)
COUNTRY_DB=/var/lib/GeoIP/GeoLite2-Country.mmdb
if [ $# -ne 1 ]; then
echo "Usage: $(basename $0) <ip_address>" 1>&2
exit 0 # return true in case of config issue
fi
# Fetch the country code using geoip
COUNTRY=$(${GEOIP_BIN} -f ${COUNTRY_DB} -i $1 country iso_code | awk -F'"' '{print $2}' | xargs)
# Handle errors in geoip lookup
if [[ $COUNTRY == Error* || -z $COUNTRY ]]; then
RESPONSE="DENY"
else
if [[ " $ALLOW_COUNTRIES " =~ " $COUNTRY " ]]; then
RESPONSE="ALLOW"
else
RESPONSE="DENY"
fi
fi
# Log and exit appropriately
logger "$RESPONSE sshd connection from $1 ($COUNTRY)"
if [ "$RESPONSE" = "ALLOW" ]; then
exit 0
else
exit 1
fi
Save the script (e.g. in the /opt/ directory) and give it execute permissions:
sudo nano /opt/geoip-ssh.sh
Paste the script content into the file and save it. Then, set the appropriate permissions:
sudo chmod 700 /opt/geoip-ssh.sh
Edit the /etc/hosts.allow file to use the script for SSH connections:
sudo nano /etc/hosts.allow
Add the following line:
sshd: ALL: aclexec /opt/geoip-ssh.sh %a
Next, edit the /etc/hosts.deny file to deny all other SSH connections:
sudo nano /etc/hosts.deny
Add the following line:
sshd: ALL
Before finalizing this setup, it's crucial to test it extensively. Misconfigurations can result in locking yourself out of the server. Ensure you have alternative access methods (such as a console or another user account) before applying these changes.
By following these steps, you can enhance the security of your Linux server by restricting SSH access based on geographic location. Using tools like geoipupdate and mmdblookup with the free MaxMind GeoLite2 database, you can ensure that only trusted countries can connect to your SSH service.
Remember to test thoroughly to avoid accidental lockouts. This method provides an additional layer of security, making it harder for unauthorized users from untrusted locations to gain access to your server.