A few quick notes for other folks who are geoblocking the UK. I just set up a basic geoblock with Nginx on Debian. This is all stuff you can piece together, but the Maxmind and Nginx docs are a little vague about the details, so I figure it’s worth an actual writeup. My Nginx expertise is ~15 years out of date, so this might not be The Best Way to do things. YMMV.
First, register for a free MaxMind account; you’ll need this to subscribe to their GeoIP database. Then set up a daemon to maintain a copy of the lookup file locally, and Nginx’s GeoIP2 module:
apt install geoipupdate libnginx-mod-http-geoip2
Create a license key on the MaxMind site, and download a copy of the config file you’ll need. Drop that in /etc/GeoIP.conf
. It’ll look like:
AccountID XXXX
LicenseKey XXXX
EditionIDs GeoLite2-Country
The package sets up a cron job automatically, but we should grab an initial copy of the file. This takes a couple minutes, and writes out /var/lib/GeoIP/GeoLite2-Country-mmdb
:
geoipupdate
The GeoIP2 module should already be loaded via /etc/nginx/modules-enabled/50-mod-http-geoip2.conf
. Add a new config snippet like /etc/nginx/conf.d/geoblock.conf
. The first part tells Nginx where to find the GeoIP database file, and then extracts the two-letter ISO country code for each request as a variable. The map
part sets up an $osa_geoblocked
variable, which is set to 1
for GB, otherwise 0
.
geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_iso_code country iso_code;
}
map $geoip2_data_country_iso_code $osa_geoblocked {
GB 1;
default 0;
}
Write an HTML file somewhere like /var/www/custom_errors/osa.html
, explaining the block. Then serve that page for HTTP 451 status codes: in /etc/nginx/sites-enabled/whatever
, add:
server {
...
# UK OSA error page
error_page 451 /osa.html;
location /osa.html {
internal;
root /var/www/custom_errors/;
}
# When geoblocked, return 451
location / {
if ($osa_geoblocked = 1) {
return 451;
}
}
}
Test your config with nginx -t
, and then service nginx reload
. You can test how things look from the UK using a VPN service, or something like locabrowser.
This is, to be clear, a bad solution. MaxMind’s free database is not particularly precise, and in general IP lookup tables are chasing a moving target. I know for a fact that there are people in non-UK countries (like Ireland!) who have been inadvertently blocked by these lookup tables. Making those people use Tor or a VPN sucks, but I don’t know what else to do in the current regulatory environment.
Many thanks for this tutorial, got it working. Except that I reversed it, because I want to allow access only from the UK, so I test for $osa_geoblocked = 0. This works for blocking countries outside the UK, tested using Opera’s VPN. However I have one big issue - requests from my own 192.168.1.n network are also blocked. Not sure what country code is being returned for these addresses, if any, think I’ll need to dig into nginx config to work out how to bypass the geoip test for these addresses.