Skip to main content

Working with GeoIP

1. Installing GeoIP Module

The GeoIP module for Nginx allows you to determine the geographical location of a client based on their IP address. It is not included in the default Nginx build and must be installed separately.

Installation Method Description Notes
Compile from Source Download Nginx source code and compile with the GeoIP module. Requires building Nginx from source with the --with-http_geoip_module flag.
Package Manager (Ubuntu/Debian) Use apt to install Nginx with GeoIP support. Ensure the nginx-module-geoip package is installed.
Package Manager (CentOS/RHEL) Use yum or dnf to install Nginx with GeoIP support. Install the nginx-module-geoip package or build from source.

Example: Compile Nginx with GeoIP Module

./configure --with-http_geoip_module --with-http_geoip_module=dynamic
make
make install
Note: The GeoIP module requires the libgeoip library to be installed on the system.
Warning: Ensure that the GeoIP database files (e.g., GeoIP.dat) are available and correctly configured in the Nginx configuration.

2. Loading GeoIP Database

Directive Values Description
geoip_country path/to/GeoIP.dat Path to the GeoIP country database file
geoip_city path/to/GeoLiteCity.dat Path to the GeoIP city database file
geoip_org path/to/GeoIPOrg.dat Path to the GeoIP organization database file

Example: Loading GeoIP Database

http {
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    geoip_city /usr/share/GeoIP/GeoLiteCity.dat;
    geoip_org /usr/share/GeoIP/GeoIPOrg.dat;

    server {
        listen 80;
        server_name example.com;

        location / {
            add_header X-Country $geoip_country_code;
            add_header X-City $geoip_city_name;
        }
    }
}

3. Using GeoIP Variables

Variable Description Example Value
geoip_country_code Country code (2-letter ISO) US
geoip_country_code3 Country code (3-letter ISO) USA
geoip_country_name Full country name United States
geoip_region Region or state California
geoip_city City name San Francisco
geoip_latitude Latitude of city 37.7749
geoip_longitude Longitude of city -122.4194

Example: Setting a variable based on country

map $geoip_country_code $is_usa {
    default no;
    US yes;
}

server {
    listen 80;
    server_name example.com;

    if ($is_usa = yes) {
        return 403 "Access denied for USA";
    }

    location / {
        proxy_pass http://backend;
    }
}
Note: These variables are only available after the GeoIP module has been loaded and the database is properly configured.

4. Implementing Geo-blocking

Directive Description Example
geoip_country Maps IP addresses to country codes using the GeoIP database geoip_country /usr/share/GeoIP/GeoIP.dat;
geoip_city Maps IP addresses to city information using the GeoIP database geoip_city /usr/share/GeoIP/GeoLiteCity.dat;
geoip_org Maps IP addresses to organization names using the GeoIP database geoip_org /usr/share/GeoIP/GeoIPOrg.dat;

Example: Blocking Access from Specific Countries

geoip_country $geoip_country_code;

map $geoip_country_code $allowed_country {
    default no;
    US yes;
    CA yes;
    GB yes;
}

server {
    listen 80;
    server_name example.com;

    if ($allowed_country = no) {
        return 403;
    }

    location / {
        # Allow access to allowed countries
        root /var/www/html;
    }
}
Note: Ensure the GeoIP database files are installed and accessible by Nginx. Common paths include /usr/share/GeoIP/ or /var/lib/GeoIP/.
Warning: GeoIP databases are not 100% accurate and may block or allow access based on incorrect location data. Regular updates of the database are recommended.

5. Redirecting by Location

Directive Description Example
geoip_country Maps IP to country code geoip_country $geoip_country_code;
geoip_city Maps IP to city name geoip_city $geoip_city;
geoip_org Maps IP to organization geoip_org $geoip_org;

Example: Redirect based on country code

map $geoip_country_code $redirect_country {
    default "";
    US "https://example.com/us";
    GB "https://example.com/uk";
}

server {
    listen 80;
    server_name example.com;

    if ($redirect_country) {
        return 301 $redirect_country;
    }
}
Note: Ensure libgeoip-dev is installed for GeoIP module support.

6. Setting Language by Country

Directive Description Values Notes
geoip_country_file Path to the GeoIP country database file /etc/nginx/geoip/GeoIP.dat Required for country-based lookups
geoip_city_file Path to the GeoIP city database file /etc/nginx/geoip/GeoLiteCity.dat Optional, for city-level lookups
geoip_org_file Path to the GeoIP organization database file /etc/nginx/geoip/GeoIPOrg.dat Optional, for organization-level lookups

Example: Setting Language Based on Country

map $geoip_country_code $lang {
    default "en";
    US "en";
    GB "en";
    FR "fr";
    DE "de";
    JP "ja";
}

server {
    listen 80;
    server_name example.com;

    location / {
        add_header Content-Language $lang;
        root /var/www/html;
    }
}
Note: The $geoip_country_code variable is set by the geoip_country_file directive. Ensure that the GeoIP database files are correctly installed and accessible by Nginx.

7. Using GeoIP2 Module

Directive Description Default Notes
geoip2 Sets the database file for GeoIP2 data none Required to enable the module
geoip2_proxy Defines an IP address or CIDR range to trust for forwarded IP addresses none Useful when behind a proxy or load balancer
geoip2_proxy_recursive Enables recursive proxy detection off When enabled, checks all forwarded IP addresses in the X-Forwarded-For header

Example: Setting up GeoIP2 Module

load_module modules/ngx_http_geoip2_module.so;

http {
    geoip2 /etc/nginx/GeoLite2-City.mmdb;
    
    map $geoip2_data_city_name $city {
        default "Unknown";
        ~^(.*) $1;
    }

    server {
        listen 80;
        location / {
            add_header X-City $city;
            return 200 "City: $city\n";
        }
    }
}
Note: The GeoIP2 module requires the libmaxminddb library to be installed on the system.
Warning: Ensure that the database file path is correct and accessible by the Nginx process. Incorrect paths will result in errors or missing data.
Variable Description Usage Example
$geoip2_data_city_name City name from the GeoIP2 database add_header X-City $geoip2_data_city_name;
$geoip2_data_country_code Country code (e.g., US, CA) return 200 "Country: $geoip2_data_country_code";
$geoip2_data_country_name Full country name (e.g., United States) return 200 "Country: $geoip2_data_country_name";
$geoip2_data_region_name Region or state name (e.g., California) return 200 "Region: $geoip2_data_region_name";
$geoip2_data_timezone Timezone information (e.g., America/Los_Angeles) return 200 "Timezone: $geoip2_data_timezone";

GeoIP2 Module Summary

  • Module: ngx_http_geoip2_module
  • Database: Requires GeoLite2-City.mmdb or similar
  • Variables: Available through $geoip2_data_* variables
  • Proxy Support: Use geoip2_proxy and geoip2_proxy_recursive for forwarded IPs

8. Configuring MaxMind Databases

Directive Description Values Notes
geoip_country Sets the path to the country database file geoip_country /path/to/GeoIP.dat; Required for country-based geo targeting
geoip_city Sets the path to the city database file geoip_city /path/to/GeoLiteCity.dat; Used for city-level geolocation
geoip_org Sets the path to the organization database file geoip_org /path/to/GeoIPOrg.dat; Used for organization-based geolocation
geoip_proxy Defines trusted proxy addresses for IP geolocation geoip_proxy 192.168.0.0/16; Prevents spoofing of client IPs
geoip_proxy_recursive Enables recursive proxy address checking geoip_proxy_recursive on; Useful for complex proxy setups

Example: Setting up MaxMind Country Database

http {
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    geoip_city /usr/share/GeoIP/GeoLiteCity.dat;

    map $geoip_country_code $is_eu {
        default no;
        AT yes;
        BE yes;
        BG yes;
        HR yes;
        CY yes;
        CZ yes;
        DK yes;
        EE yes;
        FI yes;
        FR yes;
        DE yes;
        GR yes;
        HU yes;
        IE yes;
        IT yes;
        LV yes;
        LT yes;
        LU yes;
        MT yes;
        NL yes;
        NO yes;
        PL yes;
        PT yes;
        RO yes;
        SK yes;
        SI yes;
        ES yes;
        SE yes;
        GB yes;
    }
}
Note: Ensure the MaxMind database files are downloaded and placed in the correct directory. The GeoIP.dat file is used for country-level geolocation, while GeoLiteCity.dat provides city-level details.
Warning: The geoip_proxy directive should be configured carefully to avoid IP spoofing in environments with proxies or load balancers.

9. Logging GeoIP Data

Directive Description Example
geoip_country Maps IP to country code (2-letter ISO) geoip_country $geoip_country_code
geoip_city Maps IP to city name geoip_city $geoip_city
geoip_org Maps IP to organization name geoip_org $geoip_org
geoip_region Maps IP to region name geoip_region $geoip_region
geoip_latitude Maps IP to latitude geoip_latitude $geoip_latitude
geoip_longitude Maps IP to longitude geoip_longitude $geoip_longitude

Example: Logging GeoIP in Access Log

log_format geoip_log '$remote_addr - $geoip_country_code - $geoip_city - $geoip_org [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';

access_log /var/log/nginx/access.log geoip_log;
Note: Ensure the GeoIP database is installed and updated regularly for accurate logging.

10. Using GeoIP with Map Directive

Directive Values Description
map $geoip_country_code Maps IP address to country code using GeoIP database
map $geoip_city Maps IP address to city name using GeoIP database
map $geoip_region Maps IP address to region name using GeoIP database

Example: Setting up GeoIP map directive

geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $country_is_eu {
    default no;
    "AT" yes;
    "BE" yes;
    "BG" yes;
    "CY" yes;
    "CZ" yes;
    "DE" yes;
    "DK" yes;
    "EE" yes;
    "ES" yes;
    "FI" yes;
    "FR" yes;
    "GB" yes;
    "GR" yes;
    "HR" yes;
    "HU" yes;
    "IE" yes;
    "IT" yes;
    "LT" yes;
    "LU" yes;
    "LV" yes;
    "MT" yes;
    "NL" yes;
    "PL" yes;
    "PT" yes;
    "RO" yes;
    "SE" yes;
    "SI" yes;
    "SK" yes;
}
Note: Ensure the GeoIP database files are installed and accessible by Nginx. The path to these files may vary depending on your OS or package manager.

Example: Using the mapped variable in a location block

location /eu-content {
    if ($country_is_eu = no) {
        return 403;
    }
}

11. Implementing Regional Content Delivery

Directive Description Example
geoip_country Maps IP addresses to country codes using the GeoIP database. geoip_country /usr/share/GeoIP/GeoIP.dat;
geoip_city Maps IP addresses to city information. geoip_city /usr/share/GeoIP/GeoLiteCity.dat;
geoip_org Maps IP addresses to organization names. geoip_org /usr/share/GeoIP/GeoIPOrg.dat;

Example: Serving Content Based on Country

geoip_country $geoip_country_code;

map $geoip_country_code $backend {
    default          "http://backend-default.example.com";
    US               "http://backend-us.example.com";
    GB               "http://backend-uk.example.com";
}

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass $backend;
    }
}
Note: Ensure the GeoIP database files are correctly installed and accessible by Nginx.
Warning: GeoIP databases require regular updates to maintain accuracy.

12. Caching GeoIP Lookups

Directive Values Description
geoip_country string Sets the variable to the country code for the client IP address.
geoip_city string Sets the variable to the city name for the client IP address.
geoip_org string Sets the variable to the organization name for the client IP address.

Example: Caching GeoIP in Nginx

http {
    geoip_country /usr/share/GeoIP/GeoIP.dat;
    geoip_city /usr/share/GeoIP/GeoLiteCity.dat;

    map $geoip_country_code $country_cache {
        default "unknown";
        US "United States";
        GB "United Kingdom";
    }

    server {
        listen 80;
        location / {
            set $country $country_cache;
            proxy_pass http://backend;
        }
    }
}
Note: Ensure the GeoIP database files are correctly installed and accessible by Nginx.
Warning: Performance can degrade if GeoIP lookups are not cached properly or if the database is outdated.

Was this article helpful?