Country Blocking

Author: Lance LeFlore

When providing VPN services, it is expected that clients will be connecting from a vast number of different subnets around the internet at-large. Because of this, it’s not entirely feasible to use a packet filter to whitelist the subnets from which clients may be connecting to the VPN server. Very often, however, one may safely assume that clients will only be connecting from a particular set of countries. This then gives us a parameter we can in turn use to whitelist client connections. For example, if one assumes his or her clients will only ever connect from the US and Czech Republic; a GeoIP lookup can be performed against the clients’ source IP to determine whether they are in fact connecting from the US or the Czech Republic.

Prerequisites

Configuration

#!/bin/sh

ALLOW_COUNTRY_CODES="CZ US"

# Make sure Ocserv passes IP_REAL
if [ "x${IP_REAL}" = "x" ]; then
  exit 1
fi

# The following provides the country code variable using the local geoip database:
# Note that this may be called ipcalc-ng on debian-based systems.
COUNTRY_CODE=$(ipcalc -g ${IP_REAL} | grep CODE | cut -d'=' -f2)

# Handle instances where COUNTRY_CODE is empty (e.g. RFC 1918 addresses)
if [ "x${COUNTRY_CODE}" = "x" ]; then
  # Fail open
  exit 0
  # Fail closed
  # exit 1
fi

for c in $ALLOW_COUNTRY_CODES; do
  if [ "${c}" = "${COUNTRY_CODE}" ]; then
    exit 0
  fi
done

# If we made it here, then COUNTRY_CODE was not found in ALLOW_COUNTRY_CODES
exit 1