Skip to content

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

  • cURL
  • Tested on Ocserv 0.11.5.

Configuration

  • Set connect-script = /usr/bin/ocserv-country-blocker in ocserv.conf.
  • Create a file with the following code at /usr/bin/ocserv-country-blocker:
#!/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
  • Be certain to set ALLOW_COUNTRY_CODES to a list of countries you'd like to whitelist VPN access from.
  • You should also decide the behavior you'd like the script exhibit in the event that FreeGeoIP does not return a country code. Currently the script "fails open" meaning that it will allow a client connection to proceed if, for some reason, FreeGeoIP does not return a country code.
  • Set the executable bit on /usr/bin/ocserv-country-blocker
  • Restart Ocserv