Nginx 不生成地理位置信息,仅透传上游已注入的地理请求头(如 CDN 提供的 CF-IPCountry),需配合 proxy_set_header 转发给后端,且必须确保上游可信、配置位置正确、后端主动读取。

Nginx 本身不内置地理位置识别能力,proxy_set_header 也不能直接“生成”地理位置信息(比如国家、城市、经纬度)。它只能传递已有字段——所以要透传地理位置,必须先让真实地理位置数据以 HTTP 请求头的形式到达 Nginx(通常由前置服务提供),再用 proxy_set_header 转发给后端。
关键逻辑是:Nginx 只负责透传,不负责解析或生成地理信息。
✅ 前置条件:地理位置数据必须已存在于请求头中
常见来源有:
-
CDN 或云厂商 WAF(如 Cloudflare、阿里云 CDN、腾讯云 CDN)
它们会在回源请求中自动添加地理相关头,例如:-
CF-IPCountry:CN(Cloudflare) -
X-Country-Code:US(部分 CDN) -
X-City:Shanghai -
X-Region:EastChina -
X-Latitude/X-Longitude
-
自建 GEO IP 服务 + Lua/OpenResty
在 Nginx 中集成ngx_http_geoip2_module或通过lua-resty-maxminddb解析$remote_addr,然后 set 自定义变量(如$geo_country_code),再透传。上游负载均衡器或 API 网关
比如 Kong、Traefik 或自研网关,在转发前已查库注入X-Geo-Country,X-Geo-City等头。
⚠️ 注意:不能信任任意客户端发送的
X-Geo-*头,必须只从可信上游(如 CDN 回源 IP 段)读取,否则可被伪造。
✅ 在 location 或 server 块中透传地理头
确认上游已注入地理头后,只需在 proxy_pass 前添加对应 proxy_set_header:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
location /api/ {
# 假设上游 CDN 已设置 CF-IPCountry、CF-IPCity 等
proxy_set_header X-Geo-Country $http_cf_ipcountry;
proxy_set_header X-Geo-City $http_cf_ipcity;
proxy_set_header X-Geo-Region $http_cf_ipregion;
proxy_set_header X-Geo-Lat $http_cf_iplat;
proxy_set_header X-Geo-Lon $http_cf_iplon;
# 或更通用写法(如果上游用标准头名)
# proxy_set_header X-Geo-Country $http_x_country_code;
# proxy_set_header X-Geo-City $http_x_city;
proxy_pass http://backend;
}说明:
-
$http_cf_ipcountry是 Nginx 内置变量,自动映射请求头CF-IPCountry的值; - 所有
$http_*变量都小写转换(CF-IPCountry→$http_cf_ipcountry); - 若上游用的是
X-Geo-Country,则用$http_x_geo_country; - 这些头会原样转发给后端,后端通过
request.getHeader("X-Geo-Country")等方式读取。
✅ 如果想自己解析 IP 地理位置(进阶)
需额外模块支持,例如:
-
安装 geoip2 模块 + MaxMind DB
配置示例:http { geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb { $geoip2_data_country_code source=$remote_addr country iso_code; $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; } server { location / { proxy_set_header X-Geo-Country $geoip2_data_country_code; proxy_set_header X-Geo-City $geoip2_data_city_name; proxy_set_header X-Geo-Lat $geoip2_data_latitude; proxy_set_header X-Geo-Lon $geoip2_data_longitude; proxy_pass http://backend; } } }
✅ 前提:Nginx 编译时启用
--with-http-geoip2-module,且数据库文件路径正确、权限可读。
❌ 常见误区提醒
-
proxy_set_header X-Geo-Country $remote_addr;—— 错!$remote_addr是 IP 字符串,不是地理位置; - 不验证上游可信性就直接透传
$http_x_geo_*—— 易被客户端伪造; - 忘记在
proxy_pass之前写proxy_set_header—— 该指令必须位于proxy_pass上方才生效; - 后端没做兼容处理,仍只读
REMOTE_ADDR—— 地理信息白传,后端代码必须主动读取X-Geo-*头。
不复杂但容易忽略。核心就三点:上游得给、Nginx 得转、后端得收。

















