Aaron Lauterer

NGINX GeoIP testing

At work I had the task to implement a redirection based on the visitors country for the company website.

I came to use this serverfault.com answer as a base for my implementation.

But how do I test this? In order to test the behavior I need to fake IP adresses from all over the world. iptables to the rescue!

Faking the source IP address

To test this I had the NGINX running in a virtual machine. In this VM the following iptables rule will rewrite the IP from the client before it reaches NGINX.

$ iptables -t nat -A INPUT -p tcp -d <serverIP> --dport 443 -s <clientIP> -j SNAT --to-source <fakeIP>

This was taken from this serverfault answer (SNAT only).

In order to change the faked IP address the current rule must be deleted. To get an overview of the currently applied rules use

$ iptables -t nat -L -n -v --line-number

The rule should be in the INPUT chain. In order to delete the rule run the following command

$ iptables -t nat -D INPUT <number>

while <number> is the number in the num column of the previous output.

After this we can run the first command again with another faked IP address.

Check what NGINX sees

It would be nice to know which IP NGINX sees and the country it detects. Of course this could be checked in the log files as well but it would be nice to see it right there in the browser.

The sub_filter directive helps with this. When an index.html file is placed in the directories where a redirect will happen to the sub_filter module can replace placeholders with NGINX variables.

A sample index.html could look like this:

Country: <country><br>
Source IP: <sourceip>

in the server or location section of the NGINX config the following needs to be placed:

sub_filter '<country>' $geoip_country_code;
sub_filter '<sourceip>' $remote_addr;

Enjoy!

Got any hints or questions? blog@aaronlauterer.com