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

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/ –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

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/
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


Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.