nginx: How To Block Visitors By Country With The GeoIP Module (Debian/Ubuntu)

Version 1.0

Author: Falko Timme

Follow me on Twitter



This tutorial explains how to use the GeoIP module with nginx to block visitors by country. This is made possible by the GeoIP database which maps users' IP addresses to countries. nginx must be compiled with the HttpGeoipModule to use the GeoIP database.

I do not issue any guarantee that this will work for you!

1 Preliminary Note

As mentioned in the introduction, nginx must be compiled with the HttpGeoipModule. To check if your nginx was compiled with that module, run:

nginx -V

If you see --with-http_geoip_module in the output, you are ready to use the GeoIP database with nginx:

[email protected]:~# nginx -V

nginx version: nginx/1.2.1

TLS SNI support enabled

configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/build/buildd-nginx_1.2.1-2.1-amd64-fMGfEu/nginx-1.2.1/debian/modules/nginx-auth-pam --add-module=/build/buildd-nginx_1.2.1-2.1-amd64-fMGfEu/nginx-1.2.1/debian/modules/nginx-echo --add-module=/build/buildd-nginx_1.2.1-2.1-amd64-fMGfEu/nginx-1.2.1/debian/modules/nginx-upstream-fair --add-module=/build/buildd-nginx_1.2.1-2.1-amd64-fMGfEu/nginx-1.2.1/debian/modules/nginx-dav-ext-module

[email protected]:~#

2 Installing The GeoIP Database

On Debian/Ubuntu, the GeoIP database can be installed as follows:

apt-get install geoip-database libgeoip1

This places the GeoIP database in /usr/share/GeoIP/GeoIP.dat.

It is possible that it is a bit outdated. Therefore we can optionally download a fresh copy from the GeoIP web site:

mv /usr/share/GeoIP/GeoIP.dat /usr/share/GeoIP/GeoIP.dat_bak

cd /usr/share/GeoIP/

wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz

gunzip GeoIP.dat.gz

3 Configuring nginx

Open /etc/nginx/nginx.conf...

vi /etc/nginx/nginx.conf

... and place this in the http {} block, before any include lines:

[...] geoip_country /usr/share/GeoIP/GeoIP.dat; map $geoip_country_code $allowed_country { default yes; FK no; FM no; EH no; } [...]

This allows all countries, except the three countries set to no (you can find a list of country codes here). To do it the other way round, i.e. block all countries and allow only a few, you'd do it this way:

[...] geoip_country /usr/share/GeoIP/GeoIP.dat; map $geoip_country_code $allowed_country { default no; FK yes; FM yes; EH yes; } [...]

Now, this actually doesn't block any country, it just sets the $allowed_country variable. To actually block countries, you must open your vhost configuration and place the following code in the server {} container (this can go inside and also outside any location {} block):

[...] if ($allowed_country = no) { return 444; } [...]

This returns the 444 error code to any visitor from a blocked country. What this does is it closes the connection without sending any headers. You can also use another error code like 403 ("Forbidden") if you like.

Reload nginx afterwards:

/etc/init.d/nginx reload

About The Author

Falko Timme is the owner of Timme Hosting (ultra-fast nginx web hosting). He is the lead maintainer of HowtoForge (since 2005) and one of the core developers of ISPConfig (since 2000). He has also contributed to the O'Reilly book "Linux System Administration".Advertisement