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.mmdbor similar - Variables: Available through
$geoip2_data_*variables - Proxy Support: Use
geoip2_proxyandgeoip2_proxy_recursivefor 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.