Skip to content

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:

  1. Make note of the IP Address and Port Number for the proxy of your choice
  2. In Chrome, access the three-dot menu and select Settings
  3. Navigate to System > Open your computer's proxy settings
  4. Click the Set up button in the Manual proxy setup > Use a proxy server section
  5. Enable Use a proxy server
  6. Enter the Proxy IP address and Port from earlier
  7. 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 as Estados 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 or 192.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

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

Additional Resources