Nginx Geo IP Module

This article explains how to get user's location such as latitude , longitude, city and also state from request using nginx geo ip module.

Hello all. Today we will see how to use nginx geo ip module to get user's location such as latitude , longitude and city from request.

First of all how to get nginx on your machine

sudo apt-get install nginx

windows users for installation refer here

Check Nginx is Installed with geo ip module or not by

 nginx -V

 

nginx version: nginx/1.10.1
built with OpenSSL 1.0.1f 6 Jan 2014
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --with-http_flv_module --with-http_geoip_module=dynamic --add-dynamic-module=/build/nginx-JCHwcf/nginx-1.10.1/debian/modules/ngx-fancyindex --add-dynamic-module=/build/nginx-JCHwcf/nginx-1.10.1/debian/modules/nchan 

--with-http_geoip_module=dynamic -> Nginx configured with GEOIP module

if you see like this

 --without-http_geo_module -> Nginx is not configured with GEOIP.
In this case do

 sudo apt-get install nginx-extras

Now let's get to work on config part

Step 1: Create geo ip directory and download IP and City databases

mkdir /etc/nginx/geoip

fire these commands in terminal or run this as shell script like below

# !bin/sh
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz -O /etc/nginx/geoip/GeoIP.dat.gz
gunzip /etc/nginx/geoip/GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz -O /etc/nginx/geoip/GeoLiteCity.dat.gz
gunzip /etc/nginx/geoip/GeoLiteCity.dat.gz

Usually i do put these commands in shell script and execute that like this

  sudo sh filename.sh

Note: We are just downloading database files and putting those files inside directory we created.

Step 2: Put these lines in /etc/nginx.conf

geoip_country /etc/nginx/geoip/GeoIP.dat;
geoip_city /etc/nginx/geoip/GeoLiteCity.dat;

Step 3: Restart Nginx by

  sudo systemctl restart nginx.service  

Step 4: Pass Request Params to backend server /etc/nginx

Country name can be accessed by $geoip_country_name

so if your using wsgi/uwsgi for your app you can pass uwsgi params from nginx like this


uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;

uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param UWSGI_SCHEME $scheme;

uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;

uwsgi_param GEOIP_COUNTRY_NAME $geoip_country_name;
uwsgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
uwsgi_param GEOIP_COUNTRY_CODE3 $geoip_country_code3;

uwsgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;
uwsgi_param GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3;
uwsgi_param GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name;
uwsgi_param GEOIP_REGION $geoip_region;
uwsgi_param GEOIP_CITY $geoip_city;
uwsgi_param GEOIP_POSTAL_CODE $geoip_postal_code;
uwsgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
uwsgi_param GEOIP_LATITUDE $geoip_latitude;
uwsgi_param GEOIP_LONGITUDE $geoip_longitude;

Save this as  uwsgi_params in  /etc/nginx/ and include this line in  /etc/nginx/nginx.conf inside http


include /etc/nginx/uwsgi_params;

Conclusion:
      In python based apps which is deployed under nginx+ uwsgi apps, In code You can access geo values by       

os.enviorn.get('GEOIP_CITY_COUNTRY_NAME')

These code samples can be found in repository

Thanks . Happy Coding !!!

Leave a comment

(Note: Comments are moderated)