Problem: I have a multi-site Apache web server, hosting localised copies of the site for many countries. I would like customer visiting the site to be automatically redirected to their country-specific site. Something similar to Google, where if you visit www.google.com you will be redirected to a country-specific site. In my case, it is www.google.co.uk
Solution: As the heading says, I will be using GeoIP module from MaxMind to achieve the solution. The GeoIP module comes in two flavours, free and paid; the difference, apart from the price, is the data file accuracy. The explanations and procedure explained here work for both flavours of GeoIP. I’m using the free version of the module, and the setup is on Debian stable, as that’s my Linux of choice. All steps shown below will work on any other versions of Linux as long as you make the configuration changes in the right files. I will try and point out the differences as they come along.
Technically, this is what happens when a request comes to the Apache web server; the GeoIP module kicks in and sets a few Apache environment variables based on the request’s REMOTE_ADDR field. The set variables are, in turn, used by the rewrite module to decide on the site the user should be redirected to.
I assume you have a working instance of Apache web server with rewrite module and can access the site from outside your network, or in other words, reachable on the Internet. Note: It doesn’t matter if Apache is running on a different port.
Step1. Install GeoIP module. Debian packages this module by default. Use the below command to install it
$ sudo apt-get install libapache2-mod-geoip
If you are using RedHat or CentOS, you might have to compile the module, as there are no binary packages. Download the latest package from here, assuming you downloaded the file mod_geoip2_1.2.7.tar.gz, follow these steps from the download folder.
$ tar zxf mod_geoip2_1.2.7.tar.gz
$ cd mod_geoip2_1.2.7
$ apxs -i -a -L /usr/local/lib -I /usr/local/include -l GeoIP -c mod_geoip.c
Last command compiles and installs the module.
If you have just set up the RedHat or CentOS box, you might have to install this dependency httpd-devel.x86_64, gcc.x86_64, zlib-devel.x86_64, make.x86_64, wget.x86_64 before you compile.
If you get an error during apxs compile, check that you have GeoIP’s C API installed. If not, download it from here. Read the INSTALL file before compiling and installing the C APIs. Usually it’s just these three commands
$ ./configure && make && make install
To complete this step, restart Apache and check that the GeoIP module is loaded. This is done with the following command
$ sudo apachectl -t -D [DUMP_MODULES] | grep geo
geoip_module (shared)
Syntax OK
If you get a response like the one above, then you are through this step.
On RedHat or CentOS, you have to use the full path to apachectl command
Step2. Set up a named virtual host. There are quite a few differences between the way Debian manages Apache configuration files and that of RedHat. I’m assuming that you know how to set up NameVirtualHost on RedHat, as I will be only showing the Debian side of things.
Create three folders under /var/www/ like uk, us and fr, and in each create an index.html file with the following content
<html>
<body>
<h1>XX Site</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body>
</html>
Replace ‘XX’ with the country name.
Create three files named uk_site, us_site, fr_site under /etc/apache2/sites-available with following content
ServerAdmin webmaster@localhost
DocumentRoot /var/www/xx
ServerName xx.website.com
# mod_rewrite options
RewriteEngine On
RewriteOptions Inherit
ErrorLog logs/xx-website-error_log
CustomLog logs/xx-website-access_log
Replace xx with site-specific code, i.e. either of uk, us or fr
Enable the above-created site configurations and restart the Apache server
$ sudo a2dissite default
$ sudo a2ensite uk_site us_site fr_site
$ sudo apachectl restart
First command disables the existing default site. Once Apache is restarted, test if you can see all three sites. You might have to add ServerName values to your hosts file corresponding to the Apache server’s local IP address. If you can access all three sites, you have completed this step.
Step3. As all the required setup is complete, let’s configure the GeoIP module. Download the latest binary data file containing the IP ranges from
here, extract it and move it to a known location. Create a file geoip-rewrite.conf under /etc/apache2/ directory with the following content.
GeoIPEnable On
GeoIPDBFile /etc/apache2/geoip/GeoIP.dat
RewriteEngine On
#Variable to identify the source
SRC_EXTERNAL_ADDR=TRUE
# If accessing from private network allow access to all sites
SetEnvIf REMOTE_ADDR ^10\. SRC_EXTERNAL_ADDR=TRUE
SetEnvIf REMOTE_ADDR ^172\.[1-3]{1}\d{1}. SRC_EXTERNAL_ADDR=TRUE
SetEnvIf REMOTE_ADDR ^192\.168\. SRC_EXTERNAL_ADDR=TRUE
# You can append your external IP address here
# SetEnvIf REMOTE_ADDR xxx\.xx\.xx\.xx SRC_EXTERNAL_ADDR=TRUE
# UK Site rewrite
RewriteCond %{ENV:SRC_EXTERNAL_ADDR} !^TRUE$
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^GB$
RewriteCond %{HTTP_HOST} !^uk.website.com [NC]
RewriteRule ^(.*)$ http://uk.website.com$1 [L]
# US Site rewrite
RewriteCond %{ENV:SRC_EXTERNAL_ADDR} !^TRUE$
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^US$
RewriteCond %{HTTP_HOST} !^us.website.com [NC]
RewriteRule ^(.*)$ http://us.website.com$1 [L]
# French Site rewrite
RewriteCond %{ENV:SRC_EXTERNAL_ADDR} !^TRUE$
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^FR$
RewriteCond %{HTTP_HOST} !^fr.website.com [NC]
RewriteRule ^(.*)$ http://fr.website.com$1 [L]
Add geoip-rewrite.conf to httpd.conf under the /etc/apache2/ directory
If httpd.conf file is not present, create one.
Restart Apache and try to access all sites locally. If that works, you are done with this step.
Step4. Testing with a country-specific IP address. This is easy to do if your browser of choice has some sort of extension to allow you to switch proxies. If you are a Google Chrome user, as I am, ProxySwitchy offers this functionality. If you use Firefox, check FoxyProxy. Install the extension in your browser, check for country-specific web proxies online, key that in to your extension and try accessing the three sites we put up earlier. Based on the IP address you are coming from, you will be directed to the right country site.
If you have added the Apache web server’s local address in the hosts file, replace the local IP of the Apache web server with its external IP address. You still have to keep ServerName names unless those names are registered in your local or external DNS.