nginx中应使用ngx_http_geoip2_module替代已弃用的原生geoip模块,加载geolite2.mmdb数据库,通过geoip2指令映射国家、城市等变量,结合real_ip模块还原真实客户端ip后写入自定义日志格式。

在 Nginx 中通过 GeoIP 模块记录客户端地理位置,核心是启用模块、加载 IP 地理数据库,并将相关变量写入日志格式。注意:现代 Nginx(1.11.3+)已弃用原生 ngx_http_geoip_module,推荐改用 ngx_http_geoip2_module(需手动编译或使用支持该模块的发行版,如 OpenResty 或某些第三方包)。
确认并安装 GeoIP2 模块
原生 GeoIP 模块仅支持旧版 MaxMind GeoLite Legacy(已停更),且不支持 IPv6 和最新数据格式。GeoIP2 是当前标准:
- 下载 MaxMind GeoLite2 City/ Country 数据库(
.mmdb格式),注册免费账号获取 License Key 后下载 - 安装
libmaxminddb库(系统包管理器可装,如 Ubuntu 执行sudo apt install libmaxminddb0 libmaxminddb-dev) - 确保 Nginx 编译时包含
--add-module=../ngx_http_geoip2_module;若用 OpenResty,默认已集成 - 验证模块是否生效:
nginx -V 2>&1 | grep -o geoip2应有输出
配置 GeoIP2 模块加载数据库
在 http 块中添加如下配置,指定数据库路径和变量映射:
http {
geoip2 /path/to/GeoLite2-City.mmdb {
$geoip2_data_country_code source=$remote_addr country iso_code;
$geoip2_data_country_name source=$remote_addr country names en;
$geoip2_data_city_name source=$remote_addr city names en;
$geoip2_data_latitude source=$remote_addr location latitude;
$geoip2_data_longitude source=$remote_addr location longitude;
}
}
说明:
– source=$remote_addr 表示基于客户端真实 IP 解析(若经代理,需先用 real_ip 模块还原)
– 变量名可自定义,但需与日志格式中引用一致
– 若只记录国家,可精简字段以提升性能
自定义日志格式并启用
在 http 或 server 块中定义含地理信息的日志格式:
log_format geoip '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$geoip2_data_country_code "$geoip2_data_country_name" '
'"$geoip2_data_city_name" $geoip2_data_latitude/$geoip2_data_longitude';
然后在 server 或 location 中应用:
access_log /var/log/nginx/access_geo.log geoip;
重启 Nginx 后,访问日志将类似:
192.168.1.100 - - [10/Jan/2024:14:22:33 +0000] "GET / HTTP/1.1" 200 1234 "-" "curl/7.68.0" CN "China" "Shanghai" 31.2304/121.4737处理代理与真实 IP(关键!)
若网站前端有 CDN、负载均衡或反向代理(如 Cloudflare、Nginx 自身 proxy_pass),$remote_addr 将是代理 IP,导致地理位置错乱。必须配合 real_ip 模块还原原始客户端 IP:
- 在
http块中配置可信代理段:set_real_ip_from 10.0.0.0/8;(根据实际代理网段调整) - 指定获取真实 IP 的请求头:
real_ip_header X-Forwarded-For;或X-Real-IP(与上游一致) - 确保
geoip2指令中的source仍为$remote_addr—— 此时它已被real_ip替换为真实 IP
未正确配置 real_ip 是地理信息不准的最常见原因。











