Playing with Nginx GeoIP and Substitution modules

Frederic Cambus April 03, 2013 [Nginx]

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-explanatory: 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 information about our IP address, geolocation, and a map.

A slightly more elaborate example is available here.