要让后端服务获取真实客户端IP,需前端Nginx正确转发X-Real-IP/X-Forwarded-For头、后端Nginx启用realip模块校验可信代理、后端应用显式读取HTTP_X_REAL_IP;多级代理时须逐级传递并完整配置可信源。

要让后端服务拿到真实的客户端IP,不能只靠加几个请求头,得从前端代理传递、Nginx自身识别、再到后端解析三步协同完成。单点配置漏掉任意一环,IP就可能错成Nginx本机地址或被伪造。
前端Nginx必须正确设置转发头
在 location 块中添加以下标准头字段:
-
X-Real-IP:设为
$remote_addr,表示当前连接的直接上游IP(首层代理即用户真实IP) -
X-Forwarded-For:用
$proxy_add_x_forwarded_for,它会自动追加当前$remote_addr到已有值末尾,保留完整链路 -
X-Forwarded-Proto:设为
$scheme,透传 http/https 协议,避免后端误判安全状态 - 可选补充
X-Forwarded-Host和X-Forwarded-Port,方便后端生成正确跳转URL
后端Nginx需启用realip模块并限定可信源
仅靠header传递不安全,必须配合 http_realip_module 做可信校验。确认模块已启用(nginx -V | grep http_realip_module),再在 http 或 server 块中配置:
-
set_real_ip_from:逐行列出所有可信代理出口IP或网段(如
192.168.1.0/24、203.0.113.5),不可写0.0.0.0/0 -
real_ip_header:指定从哪个头取真实IP,推荐
X-Real-IP(比X-Forwarded-For更可控) -
real_ip_recursive on:开启递归解析,Nginx会从右往左剔除已知代理IP,最终把第一个非代理IP赋给
$remote_addr
后端应用必须主动读取并信任这些头
Nginx只负责“发”,后端框架默认仍读 REMOTE_ADDR(即Nginx IP)。需显式配置解析逻辑:
-
Java Spring Boot:设
server.forward-headers-strategy=framework,并确保TomcatServletWebServerFactory启用setRemoteIpHeader("X-Real-IP") -
Python Flask:使用
ProxyFix中间件,明确指定num_proxies或trusted_hosts -
Node.js Express:调用
app.set('trust proxy', true),并确认Nginx已透传X-Forwarded-For和X-Forwarded-Proto - 通用建议:优先读
HTTP_X_REAL_IP(经realip模块校验),其次解析HTTP_X_FORWARDED_FOR的首个非私有IP,最后才 fallback 到REMOTE_ADDR
多级代理场景下的关键细节
若请求经过CDN、WAF或多个Nginx节点,$remote_addr 会变成上一跳IP,此时 X-Forwarded-For 格式为 用户IP, Nginx-A出口IP, Nginx-B出口IP:
- 每级代理都必须设置
X-Real-IP $remote_addr和X-Forwarded-For $proxy_add_x_forwarded_for,缺一不可 - 最末端Nginx的
set_real_ip_from必须覆盖全部中间代理IP,否则无法正确剥离 - 禁止客户端直接构造
X-Forwarded-For请求——该字段可伪造,必须依赖set_real_ip_from + real_ip_header双重约束 - 日志中建议用
$http_x_real_ip替代$remote_addr记录真实IP,更可靠











