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

Want to support HowtoForge? Become a subscriber!
 
Submitted by falko (Contact Author) (Forums) on Mon, 2012-08-27 17:18. :: Debian | Ubuntu | Web Server | nginx

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

Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>
Follow me on Twitter
Last edited 08/21/2012

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:

root@server1:~# 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
root@server1:~#

 

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

 

4 Links

 

About The Author

Falko Timme is the owner of Boost Your Site mit Timme Hosting - ultra-schnelles nginx-WebhostingTimme 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".


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.