Since the GeoLite legacy database has been discontinued, we now have to use the GeoLite2 database to get new updates to the database. This will be a followup article from the post i made about the legacy database. As the new GeoLite2 database uses a new format (maxminddb) we couldn’t just switch to the new database. Nginx also needed to be compiled with the geoip2 modul. And with Aptalca’s pull request on the alpine repo added it will just be a matter of a minor update to the nginx.conf
file!
GeoLite2 database
As of 12/30/19 you have to sign up to Maxmind to be able to download the database. https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases/
Create an account and go to your account page to download the database.
Download the database and extract the .mmdb file to the folder of you choice. I’ll be using /config/geoip2db/
for my setup.
NGINX
In your nginx.conf file add the following in the http {
block
geoip2 /config/geoip2db/GeoLite2-City.mmdb {
auto_reload 1d;
$geoip2_data_country_code country iso_code;
}
# GEO IP BLOCK SITE 1
map $geoip2_data_country_code $allowed_country {
default no;
<YOUR-COUNTRY-CODE> yes; # e.g. US for United States
}
# For allowing lan access
geo $allow_list {
default no;
IP/CIDR yes; # e.g. 192.168.1.0/24 yes;
}
Instead of <YOUR-COUNTRY-CODE>
add your own country code from this list. This will block all other countries than the one you choose. You can also add more than one country if you want.
US yes;
CA yes;
GB yes;
The IP/CIDR
is for allowing you to access the domain on your LAN.
Check out https://www.aelius.com/njh/subnet_sheet.html if you are wondering what your CIDR notation is. Most often it will be /24 (netmask 255.255.255.0)
To find your netmask run ipconfig /all
on windows or ifconfig | grep netmask
on linux.
Note: The
IP/CIDR
part is only needed if you set default tono
Setting default to no
means that it will block any IP addresses from the database not set to yes
, even local ones.
For it to actually block you need to add this in your server blocks
inside the proxy-confs
and site-confs
folder:
# COUNTRY GEO BLOCK
if ($allow_list = yes) {
set $allowed_country yes;
}
if ($allowed_country = no) {
return 444;
}
Here is an example using the unifi-controller.subdomain.conf
in proxy-confs
:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name unifi.*;
include /config/nginx/ssl.conf;
#COUNTRY GEO BLOCK
if ($allow_list = yes) {
set $allowed_country yes;
}
if ($allowed_country = no) {
return 444;
}
client_max_body_size 0;
# enable for ldap auth, fill in ldap details in ldap.conf
#include /config/nginx/ldap.conf;
# enable for Authelia
#include /config/nginx/authelia-server.conf;
location / {
# enable the next two lines for http auth
#auth_basic "Restricted";
#auth_basic_user_file /config/nginx/.htpasswd;
# enable the next two lines for ldap auth
#auth_request /auth;
#error_page 401 =200 /ldaplogin;
# enable for Authelia
#include /config/nginx/authelia-location.conf;
include /config/nginx/proxy.conf;
resolver 127.0.0.11 valid=30s;
set $upstream_app unifi-controller;
set $upstream_port 8443;
set $upstream_proto https;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
proxy_buffering off;
}
}
3. If you host several websites and want a different country block just add another with a different variable ($allowed_country2
):
# COUNTRY GEO BLOCK 2
if ($allowed_country2 = no) {
return 444;
}
As default
is set to yes
it will allow every country except the country codes set to no
# GEO IP BLOCK DOMAIN 2
map $geoip2_data_country_code $allowed_country2 {
default yes;
CN no; #China
RU no; #Russia
HK no; #Hong Kong
IN no; #India
IR no; #Iran
VN no; #Vietnam
TR no; #Turkey
EG no; #Egypt
MX no; #Mexico
JP no; #Japan
KR no; #South Korea
KP no; #North Korea :)
PE no; #Peru
BR no; #Brazil
UA no; #Ukraine
ID no; #Indonesia
TH no; #Thailand
}
I made this list based on the Spamhaus statistics and Aakamai’s state of the internet report.
Blocked
You can test if it worked with a VPN or do a performance test from a location that is blocked here https://www.webpagetest.org/
TIP! This database gets updated!
By setting up a cronjob you can easily automate the update process.
I use the Unraid User Scripts plugin and set a cronjob to run every day but the GeoLite2 Country and City databases are updated on the first Tuesday of each month, so choose whatever suits your needs.
Click on Add New Script
→ Enter the name → Click on the name of the script and then Edit Script
Go to the licence keys page and create a license key.
Select no
when asked if you want to use the key with geoupdate.
Replace XXXXXXXXXX with your license key.
#!/usr/bin/env bash
licensekey="XXXXXXXXXXXXX"
wget -O /tmp/GeoLite2-City.tar.gz "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=${licensekey}&suffix=tar.gz"
tar -xvf /tmp/GeoLite2-City.tar.gz -C /tmp/ --wildcards "*.mmdb" --strip 1
mv /tmp/GeoLite2-City.mmdb /mnt/user/appdata/swag/geolite2/
chown 911:911 /mnt/user/appdata/letsencrypt/geolite2/GeoLite2-City.mmdb
Set the schedule to Schedule Daily or whenever you’d like.
Click Run In Background
and then Apply
Cloudflare
If you use Cloudflare you will need to add the following in nginx so that it won’t block the Cloudflare IP but the actual IP of the visitor. If you don’t do this you will get false positives.