要让后端获取真实客户端IP,必须配置三项:proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; 多级代理时还需set_real_ip_from与real_ip_header配合校验可信来源。

要让后端服务拿到真实的客户端 IP,不能只靠默认转发——Nginx 默认把后端看到的源 IP 当作自己的地址(即 $server_addr),所以必须显式设置请求头,并确保这些头被正确构造和信任。
基础三项必须配置
这三行是传递真实 IP 的最小可行组合,缺一不可:
-
记录最外层可信 IP:
proxy_set_header X-Real-IP $remote_addr;—— 把直连 Nginx 的客户端或上一级代理的 IP 写入该头,前提是这个连接本身可信 -
追加完整转发链路:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;—— 不覆盖原有值,而是把$remote_addr追加到已有的X-Forwarded-For后面,适合多级代理(如 CDN → Nginx → 后端) -
透传原始 Host 信息:
proxy_set_header Host $host;—— 防止后端因 Host 错误返回 404 或路由错乱,尤其在虚拟主机或多租户场景中很关键
应对多层代理(CDN、WAF、前置 LB)
如果请求经过 CDN 或云 WAF,$remote_addr 就不再是真实用户 IP,而是 CDN 节点 IP。这时需要两步配合:
- 用
set_real_ip_from声明可信代理网段,例如:set_real_ip_from 104.28.0.0/16;<br>set_real_ip_from 172.64.0.0/13;
- 指定从哪个请求头提取真实 IP:
real_ip_header X-Forwarded-For;(或X-Real-IP,取决于 CDN 的行为) - 启用后,
$remote_addr会自动更新为解析出的真实客户端 IP,后续proxy_set_header X-Real-IP $remote_addr;才真正有效
避免常见陷阱
有些写法看似合理,实则埋雷:
- ❌
proxy_set_header X-Forwarded-For $remote_addr;—— 直接覆盖,丢失原始链路,不利于审计和防伪造 - ❌
proxy_set_header X-Real-IP $http_x_forwarded_for;—— 未经校验直接信任,可能被客户端伪造 - ❌ 忘记配
underscores_in_headers on;—— 如果后端头含下划线(如X_Real_IP),Nginx 默认丢弃 - ✅ 推荐始终搭配
proxy_set_header X-Forwarded-Proto $scheme;—— 让后端知道是 HTTP 还是 HTTPS,避免重定向死循环
验证是否生效
可在后端服务中打印收到的请求头,重点检查:
-
X-Real-IP是否为公网可访问的真实 IPv4/IPv6 地址 -
X-Forwarded-For是否形如a.b.c.d, e.f.g.h, i.j.k.l(多个 IP 用逗号分隔),最左边应是用户真实 IP -
Host和X-Forwarded-Proto是否与原始请求一致


















