Playing with Nginx GeoIP and Substitution modules

In this tutorial, we will build a site displaying the visitor IP address and geolocation by leveraging the power of nginx GeoIP and Substitution modules. If you are using Debian stable, the default nginx package have these modules compiled-in. In case you are using backports, then installing either nginx-full or nginx-extras will do.

We start by fetching and unpacking the GeoIP Country and City databases :

mkdir -p /usr/share/GeoIP
cd /usr/share/GeoIP
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip *gz

We now edit nginx.conf to add directives specifying the path to the GeoIP database files, within the http block :

http {

	...

	geoip_country  /usr/share/GeoIP/GeoIP.dat;
	geoip_city     /usr/share/GeoIP/GeoLiteCity.dat;
}

We then edit the site configuration file to add the following content within the location block :

location / {
	
	...

	set $location $geoip_city_country_name;

	if ($geoip_city)
	{
		set $location "$geoip_city, $geoip_city_country_name";
	}

	set $map "http://maps.google.com/maps/api/staticmap?center=$geoip_latitude,$geoip_longitude&zoom=12&size=640x250&markers=$geoip_latitude,$geoip_longitude&sensor=false";

	sub_filter IP_ADDRESS_PLACEHOLDER</h3>
	'$remote_addr</h3><p><strong>Your location :</strong> $location</p><p><strong>Latitude :</strong> $geoip_latitude</p><p><strong>Longitude :</strong> $geoip_longitude</p><img alt="Geolocation" src="$map" />';
}

The instructions above are pretty much self-explaining : we start by setting the $location and $map variables, and we then use the sub_filter command to insert the generated content within nginx response.

Finally, we create a simple index.html file (note the IP_ADDRESS_PLACEHOLDER text which will get dynamically replaced) :

<!DOCTYPE html>
<html>
   <head> 
		<meta charset="utf-8">
		<title>Playing with Nginx GeoIP and Substitution modules</title> 
   </head>
   <body>
      <h1>Your IP address is :</h1>
      <h3>IP_ADDRESS_PLACEHOLDER</h3>
   </body>
</html>

Let’s relaunch nginx and point our browser to our newly created site : if everything goes well, we should be greeted with informations about our IP address, geolocation, and a map.

A slightly more elaborate example is available here.