Website Content Access Control by Geolocation
By: Stuart Arnett | Principal Architect
A public facing website in general is accessible to the entire world. However, there might be times when you want to allow or restrict content based on the geolocation of the user accessing the site. There are several reasons for wanting to do this, but the following are some examples:
- – Security – restrict access to the website based on country (ex., only United States users can access the website or all countries except China can access the website)
- – Translations – automatically display the website using the primary language for the country the user is located in
- – Targeted Content – display different content to the end user, (ex., redirect the user to country specific domains of the website or provide access to different pages)
To perform any of the above scenarios, the web server will need to know the geolocation of the user. This is accomplished by using the user’s IP address. This poses a problem because the location for an IP addresses can change when IP addresses are re-assigned. Luckily for us, MaxMind, Inc. (https://www.maxmind.com) provides GeoIP databases and services. The GeoIP databases / services are available in both free and paid for versions. The free versions are not as accurate as the paid for versions and only provide country, city, and ASN databases. We will be focusing on the free version of the GeoIP databases.
MaxMind also provides tools to keep the databases updated and a module for Apache HTTP server to query the databases to determine the user’s country, city, and/or ASN data. We will be setting up both the GeoIP database update tool and configuring Apache HTTP server module in the demo.
Demo Environment
We will be using the following for setting up the demo:
- – Operating System: Amazon Linux 2
- – Web Server: Apache HTTP Server 2.4
- – Geolocation: MaxMind GeoLite2 Databases, MaxMind GeoIP Update, and MaxMind DB Apache Module
MaxMind Account Setup
MaxMind requires you to setup an account and create a license key to access the MaxMind GeoLite2 databases.
- Navigate to https://www.maxmind.com/en/geolite2/signup and setup a new account.
- Once your account is set up, navigate to https://www.maxmind.com/en/my_license_key to create a new license key for GeoIP Update versions older than 3.1.1.
Note: Make sure to copy the license key, because it is not accessible after you leave the creation page.
Install and Configure MaxMind
We will now install MaxMind databases, update application, and the Apache HTTP module on Apache Linux 2.
- Log into your Apache Linux 2 instance. You will need an account with root access.
- Enable the EPEL repository on Amazon Linux 2 to access the MaxMind packages.
sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
- Install MaxMind databases and development libraries using the following command:
sudo yum install -y libmaxminddb-devel
- Amazon Linux 2 already includes an older version of the MaxMind GeoIP Update package (GeoIP) which will work but does not meet MaxMind’s latest security requirements. A request has been added to the AWS update backlog to update the package. The installed version will be used for this demo, but the configuration below will change when Amazon upgrades to the newer version.
- Update the MaxMind GeoIP Update configuration in /etc/GeoIP.conf
sudo vi /etc/GeoIP.conf
Update the UserId and LicenseKey information with your MaxMind Account ID and License Key created during your MaxMind account setup above. Update the ProductIds with the values specified below (GeoLite2-ASN GeoLite2-City GeoLite2-Country). The Product IDs are used to determine which databases will be updated.# Enter your license key here
# customers should insert their license key and user_id
# free GeoLite users should use 000000000000 as license key
LicenseKey 000000000000
# Enter your User ID here ( GeoLite only users should use 999999 as user_id )
UserId 999999# Enter the Product ID(s) of the database(s) you would like to update
# By default 106 (MaxMind GeoIP Country) is listed below
ProductIds GeoLite2-ASN GeoLite2-City GeoLite2-Country
- Update the MaxMind GeoIP Databases.
/usr/bin/geoipupdate -v
The -v command line option is used for verbose mode to provide some output when running the update. For future reference, the database files are stored in the “/usr/share/GeoIP/” folder.
- MaxMind updates the GeoIP databases on Tuesdays US Eastern time. Configure a crontab job to execute the geoipupdate program on Wednesdays to keep the databases updated with the latest information.
crontab -e
Add the following line to run the job on Wednesdays at 4am UTC.
Note: Adjust the time accordingly based on the time zone for your server.
00 04 * * 3 sudo /usr/bin/geoipupdate - Install the MaxMind Apache HTTP Module using the following commands:
sudo yum install -y gcc
sudo yum install -y httpd-develmkdir ~/download/
cd ~/download
wget https://github.com/maxmind/mod_maxminddb/releases/download/1.2.0/mod_maxminddb-1.2.0.tar.gz
tar xvzf mod_maxminddb-1.2.0.tar.gz
cd mod_maxminddb-1.2.0
./configure
sudo make install
The above commands install the gcc and httpd-devel packages which are required to build the mod_maxminddb Apache HTTP module. The module tarball is downloaded, built, and installed which adds the library to the Apache HTTP modules folder and updates the httpd.conf including the new library.
Install and Configure Apache HTTP Server
We now need to setup and configure Apache HTTP Server.
- Log into your Apache Linux 2 instance. You will need an account with root access.
- Install Apache HTTP Server using the following command:
sudo yum install -y httpd
- Start the Apache HTTP Server and verify it is working by navigating to your server with a web browser. Make sure the Apache Test page is displayed.
sudo systemctl start httpd
- Create a new httpd configuration file with the MaxMind configuration:
sudo vi /etc/httpd/conf.d/geolocation.conf
Add the following to the file:
<VirtualHost *:80>
<IfModule mod_maxminddb.c>
MaxMindDBEnable On
MaxMindDBFile ASN_DB /usr/share/GeoIP/GeoLite2-ASN.mmdb
MaxMindDBFile CITY_DB /usr/share/GeoIP/GeoLite2-City.mmdb
MaxMindDBFile COUNTRY_DB /usr/share/GeoIP/GeoLite2-Country.mmdb
MaxMindDBEnv GEOIP_ASN ASN_DB/autonomous_system_number
MaxMindDBEnv GEOIP_ASORG ASN_DB/autonomous_system_organization
# MaxMindDBEnv GEOIP_CONTINENT_CODE CITY_DB/continent/code
# MaxMindDBEnv GEOIP_CONTINENT_NAME CITY_DB/continent/names/en
# MaxMindDBEnv GEOIP_COUNTRY_CODE CITY_DB/country/iso_code
# MaxMindDBEnv GEOIP_COUNTRY_NAME CITY_DB/country/names/en
MaxMindDBEnv GEOIP_CITY_NAME CITY_DB/city/names/en
MaxMindDBEnv GEOIP_LONGITUDE CITY_DB/location/longitude
MaxMindDBEnv GEOIP_LATITUDE CITY_DB/location/latitude
MaxMindDBEnv GEOIP_CONTINENT_CODE COUNTRY_DB/continent/code
MaxMindDBEnv GEOIP_CONTINENT_NAME COUNTRY_DB/continent/names/en
MaxMindDBEnv GEOIP_COUNTRY_CODE COUNTRY_DB/country/iso_code
MaxMindDBEnv GEOIP_COUNTRY_NAME COUNTRY_DB/country/names/en
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/geoip.html$
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^US$
RewriteRule .* /geoip.html?continentCode=%{ENV:GEOIP_CONTINENT_CODE}&continent=%
{ENV:GEOIP_CONTINENT_NAME}&countryCode=%{ENV:GEOIP_COUNTRY_CODE}&country=%
{ENV:GEOIP_COUNTRY_NAME}&city=%{ENV:GEOIP_CITY_NAME}&lat=%{ENV:GEOIP_LATITUDE}&long=%
{ENV:GEOIP_LONGITUDE}&asn=%{ENV:GEOIP_ASN}&asorg=%{ENV:GEOIP_ASORG} [R,L]
</IfModule>
</VirtualHost>- – MaxMindDBEnable is used to enable or disable the MaxMind DB Apache Module.
MaxMindDBEnable On|Off - – MaxMindDBFile is used to associate a name to a MaxMind database file on disk.
MaxMindDBFile <Name> <Filesystem Path to Database File> - – MaxMindDBEnv is used to assign a database value to an environment variable. It will look up the database value based on the IP address making the current request.
MaxMindDBEnv <ENV Variable Name> <Database Name><Path to Data> - – Environment variable values are accessed using the following syntax:
An Apache rewrite condition (
%{ENV:<ENV Variable Name>}
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^US$
) is used in the above configuration to redirect all United States users accessing the website to the geoip.html page. The query parameters appended to the URL are used to display the additional data that is available within the MaxMind GeoLite2 database files and is for reference only.Note: If you are located outside of the United States, please update the country code accordingly to be able to verify the solution is working when you test.
- – MaxMindDBEnable is used to enable or disable the MaxMind DB Apache Module.
- Create HTML file geoip.html
sudo vi /var/www/html/geoip.htmlAdd the following to the file:
<h1>Geolocation Test Page</h1>
- Restart the Apache HTTP Server to load the new configuration.
sudo systemctl restart httpd - Navigate to the root page of your website. Assuming your IP is within the United States, you will be redirected to the geoip.html page. Review the query parameters added to the URL to view the additional data that is available within the MaxMind GeoLite2 database files based on your IP address.
You should now have a working website which allows geolocation-based rules to be applied to direct traffic. You can use this as a base and modify the configuration adding any additional rules you require for the geolocation business requirements in your website.
Want to learn more about geolocation rules and exclusions? Contact us today!