Enabling GeoLocation¶
Geolocation enables developers to enhance the user experience. Content and advertising may be customized for a specific user's country, showing pages more relevant to the location of the user. Admins can further enhance a site's security by blocking a client based on country. Displays can be customized for the user's environment.
Tip
While we will explain how to use the legacy GeoIP databases, we recommend the newer GeoLite2 databases, downloadable from Maxmind.
Install¶
The GeoLite2 databases are updated frequently and will regularly have to be downloaded. Maxmind explains how to automate this process. While you may want to test your configuration by downloading the databases manually, it is strongly recommended that you have them updated automatically.
OpenLiteSpeed fully supports all of the databases (both the free ones and the subscription ones). Download the databases to /usr/local/share/GeoIP
. In this guide, we will assume that you are loading the two free ones (GeoLite2-Country.mmdb
and GeoLite2-City.mmdb
) but you can follow the same instructions to set up access to the paid databases as well.
Installl the GeoIP database for CentOS users:
yum install GeoIP-data
Install other modules:
yum install GeoIP-devel zlib-devel
CRun the following command to check the database and get its URL:
rpm -ql GeoIP
It should return a database path similar to /usr/share/GeoIP/GeoIP.dat
Configure¶
In OLS WebAdmin Console, configure the database location. Navigate to Configuration > Server > General > General settings > IP to GeoLocation DB and enter the DB File Path.
It should be something like this:
/usr/local/share/GeoIP/GeoLite2-Country.mmdb
for the country database/usr/local/share/GeoIP/GeoLite2-City.mmdb
for the city database
/usr/share/GeoIP/GeoIP.dat
Set DB Name to: COUNTRY_DB
or CITY_DB
as appropriate.
Tip
DB Name is a required field, but it is not used with legacy databases. If you're using a legacy database, enter dummy text.
Navigate to Web Admin > Configurations > Your Virtual Hosts > Rewrite to add rewrite rules that will control the redirect:
<IfModule LiteSpeed>
RewriteEngine on
RewriteRule .* - [E=Cache-Control:vary=%{ENV:GEO_COUNTRY}]
</IfModule>
Refer to Maxmind for more rewrite examples.
Verify¶
To verify that geolocation is working correctly, first change your source IP by proxy to another country. Then, you can use a variety of methods to see if your proxy location is properly detected.
- Check the GEOP environment variables
- Use a database lookup tool to find information about your IP
- Use rewrite rules to redirect to location-based content
Change your source IP¶
The simplest way is to use a site like hide.me. Select one of the free countries on offer, and then visit your site anonymously from their interface.
Alternatively, you can choose a free proxy server from a site like free-proxy-list.net and then set up the proxy to work with your browser. Here's how to do that with Chrome:
- Make note of the IP Address and Port Number for the proxy of your choice
- In Chrome, access the three-dot menu and select Settings
- Navigate to System > Open your computer's proxy settings
- Click the Set up button in the Manual proxy setup > Use a proxy server section
- Enable Use a proxy server
- Enter the Proxy IP address and Port from earlier
- Click the Save button.
Now when you surf the web, you will be surfing through the Proxy Server.
Check detected GEOIP values¶
You can check your source IP via LiteSpeed's default PHP page at http://example.com/index.php?act=phpinfo
. Check the $_SERVER
variables, and look for the ones which begin with GEOIP_
.
The values should correspond to the location you are proxying through.
Tip
The GEOIP_
environment variables are based on the default environment definitions. The Advanced Configuration section below shows you how to customize them to allow you to specify environment names, display language, additional databases, etc.
Lookup the IP in the database¶
A very useful MaxMind tool is downloaded and compiled with the GeoLite2 source code release: mmdblookup
. Use this tool to view an entry in the database for a specific IP. For example, to see the country name definition for the IP address 192.0.2.0 enter from a command prompt in the openlitespeed directory:
libmaxminddb/bin/mmdblookup --file /usr/local/share/GeoIP/GeoLite2-Country.mmdb --ip 192.0.2.0 -v
The output is very detailed and can be informative as it shows you the information available in the database:
Database metadata
Node count: 561374
Record size: 24 bits
IP version: IPv6
Binary format: 2.0
Build epoch: 1530653013 (2018-07-03 21:23:33 UTC)
Type: GeoLite2-Country
Languages: de en es fr ja pt-BR ru zh-CN
Description:
en: GeoLite2 Country database
{
"continent":
{
"code":
"NA" <utf8_string>
"geoname_id":
6255149 <uint32>
"names":
{
"de":
"Nordamerika" <utf8_string>
"en":
"North America" <utf8_string>
"es":
"Norteamérica" <utf8_string>
"fr":
"Amérique du Nord" <utf8_string>
"ja":
"北アメリカ" <utf8_string>
"pt-BR":
"América do Norte" <utf8_string>
"ru":
"Северная Америка" <utf8_string>
"zh-CN":
"北美洲" <utf8_string>
}
}
"country":
{
"geoname_id":
6252001 <uint32>
"iso_code":
"US" <utf8_string>
"names":
{
"de":
"USA" <utf8_string>
"en":
"United States" <utf8_string>
"es":
"Estados Unidos" <utf8_string>
"fr":
"États-Unis" <utf8_string>
"ja":
"アメリカ合衆国" <utf8_string>
"pt-BR":
"Estados Unidos" <utf8_string>
"ru":
"США" <utf8_string>
"zh-CN":
"美国" <utf8_string>
}
}
"registered_country":
{
"geoname_id":
6252001 <uint32>
"iso_code":
"US" <utf8_string>
"names":
{
"de":
"USA" <utf8_string>
"en":
"United States" <utf8_string>
"es":
"Estados Unidos" <utf8_string>
"fr":
"États-Unis" <utf8_string>
"ja":
"アメリカ合衆国" <utf8_string>
"pt-BR":
"Estados Unidos" <utf8_string>
"ru":
"США" <utf8_string>
"zh-CN":
"美国" <utf8_string>
}
}
}
In the example above you can see:
- Date and time of the database update:
2018-07-03 21:23:33 UTC
- Type of database:
GeoLite2-Country
- List of languages available:
de en es fr ja pt-BR ru zh-CN
- And the list of available environment variable options. For example:
country/names/es
is the Spanish language version of the United States and would be displayed asEstados Unidos
Note
This example output only represents what is available in the Country database. Different databases will provide different output.
If you are using a legacy database, you won't have access to the mmdblookup
command. Instead you can use geoiplookup
/geoiplookup6
to verify GeoData is working, like so:
geoiplookup /usr/share/GeoIP/GeoIP.dat 192.0.2.10
>> GeoIP Country Edition: DE, Germany
geoiplookup /usr/share/GeoIP/GeoIP.dat 192.0.2.20
>> GeoIP Country Edition: PK, Pakistan
Verify with rewrite rules¶
Navigate to Web Admin > Configurations > Your Virtual Hosts > Rewrite:
- Set Rewrite to
Yes
- For testing purposes, set Log Level to
9
. - Add the following rules to the Rewrite Rules content:
# Redirect two specific countries
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^(CA)$
RewriteRule ^(.*)$ https://en.wikipedia.org/wiki/Canada [R,L]
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^(EU)$
RewriteRule ^(.*)$ https://en.wikipedia.org/wiki/Europe [R,L]
Now visit your site and check the log:
tail -f /PATH_TO_LSWS/log/error.log
When you are using a CA IP you should see:
[REWRITE] Rule: Match '/' with pattern '^(.*)$', result: 2
[REWRITE] Cond: Match 'CA' with pattern '^(CA)$', result: 2
[REWRITE] Source URI: '/' => Result URI: 'https://en.wikipedia.org/wiki/Canada'
With a Germany IP:
[REWRITE] Rule: Match '/' with pattern '^(.*)$', result: 2
[REWRITE] Cond: Match 'EU' with pattern '^(EU)$', result: 2
[REWRITE] Source URI: '/' => Result URI: 'https://en.wikipedia.org/wiki/Europe'
Using a Japan IP:
[REWRITE] Rule: Match '/' with pattern '^(.*)$', result: 2
[REWRITE] Cond: Match 'JP' with pattern '^(CA)$', result: -1
[REWRITE] Rule: Match '/' with pattern '^(.*)$', result: 2
[REWRITE] Cond: Match 'JP' with pattern '^(EU)$', result: -1
2
is a match, -1
is not a match
Troubleshoot¶
- If the module is not working, make sure that the httpd user (e.g.
nobody
) has read access to the GeoIP database file(s) you are using. - If the GeoIP variables do not show up make sure that the client IP address is not on a private network such as
10.0.0.0/8
,172.16.0.0/12
or192.168.0.0/16
. GeoIP can only look up public IP addresses. - The server
error.log
will show geolocation messages with a prefix of[GEO]
. Turning on Debug mode will provide quite a bit of details.
Advanced Configuration¶
Note
Advanced configuration is not available with legacy detabases.
The full power of the GeoIP2 facility requires use of the environment variables in the Litespeed Configuration. The description of the format used is designed to be as similar as possible as the Apache mod_maxminddb
environment described here specifically for the MaxMindDBEnv
variable. Each environment variable is specified in the environment text box as one line:
- The name of the environment variable that will be exported, for example
GEOIP_COUNTRY_NAME
- A space
- The logical name of the environment variable consisting of the following components:
- The name of the database as specified in the DB Name field, for example
COUNTRY_DB
- A forward slash
/
- The forward-slash-separated name of the field as displayed in
mmdblookup
. For example:country/names/en
- The name of the database as specified in the DB Name field, for example
Thus the default generates: GEOIP_COUNTRY_NAME COUNTRY_DB/country/names/en
If you wanted the country code to be displayed in Spanish, you would enter the environment variable: GEOIP_COUNTRY_NAME COUNTRY_DB/country/names/es
Note
If a variable is used by multiple databases (for example, the default GEOIP_COUNTRY_NAME
) you need to override the value in the last database specified (or all databases in case they get reordered, just to be safe).
Note that subdivisions
is an array and must be referenced by index (usually 0
or 1
). The default environment variables vary by database and are designed to be as similar to the legacy GeoIP environment variables as possible.
Country Database Defaults¶
Database name: GeoLite2-Country.mmdb
Logical name: COUNTRY_DB
Variable | Definition | Notes |
---|---|---|
GEOIP_CONTINENT_CODE | COUNTRY_DB/continent/code | 2 digit string (NA for North America) |
GEOIP_COUNTRY_CODE | COUNTRY_DB/country/iso_code | 2 digit string (US for United States) |
GEOIP_COUNTRY_CONTINENT | COUNTRY_DB/continent/code | Same as GEOIP_CONTINENT_CODE |
GEOIP_COUNTRY_NAME | COUNTRY_DB/country/names/en | Default is English, you may want to change this |
City Database Defaults¶
Database name: GeoLite2-City.mmdb
Logical name: CITY_DB
Variable | Definition | Notes |
---|---|---|
GEOIP_CITY | CITY_DB/city/names/en | Nationalized, default is English, you may want to change this |
GEOIP_CONTINENT_CODE | CITY_DB/continent/code | 2 digit string (NA for North America) |
GEOIP_COUNTRY_CODE | CITY_DB/country/iso_code | 2 digit string (US for United States) |
GEOIP_COUNTRY_CONTINENT | CITY_DB/continent/code | Same as GEOIP_CONTINENT_CODE |
GEOIP_COUNTRY_NAME | CITY_DB/country/names/en | Nationalized, default is English, you may want to change this |
GEOIP_DMA_CODE | CITY_DB/location/metro_code | An integer |
GEOIP_LATITUDE | CITY_DB/location/latitude | A signed floating point (double) |
GEOIP_LONGITUDE | CITY_DB/location/longitude | A signed floating point (double) |
GEOIP_METRO_CODE | CITY_DB/location/metro_code | An integer |
GEOIP_POSTAL_CODE | CITY_DB/postal/code | Varies by country (ZIP code in U.S.) |
GEOIP_REGION | CITY_DB/subdivisions/0/iso_code | Varies by country (State in U.S.) |
GEOIP_REGION_NAME | CITY_DB/subdivisions/0/name/en | Nationalized, default is English, varies by country (State in U.S.) |
ASN Database Defaults¶
Database name: GeoLite2-ASN.mmdb Logical name: ASN_DB
Variable | Definition | Notes |
---|---|---|
GEOIP_ISP | ASN_DB/autonomous_system_number | A 32-bit integer |
GEOIP_ORGANIZATION | ASN_DB/autonomous_system_organization | A vendor specific string |