单靠 proxy_set_header x-real-ip $remote_addr 无法稳定获取真实用户 ip,必须先启用 http_realip_module 并配置 set_real_ip_from、real_ip_header 和 real_ip_recursive,使 $remote_addr 变为真实 ip,再通过 proxy_set_header 正确透传,后端需主动读取 x-real-ip 或 x-forwarded-for 最左值。

单靠 proxy_set_header X-Real-IP $remote_addr 无法稳定获取真实用户地址。它只是“传递”一个值,而这个值是否真是用户 IP,取决于 Nginx 是否已正确识别出它——这需要前置的可信解析,不是 header 本身能解决的。
必须先让 $remote_addr 变成真实 IP
默认情况下,$remote_addr 是与 Nginx 建立 TCP 连接的上一级节点 IP(比如 CDN、WAF 或 SLB 的出口 IP),不是用户本身。要让它变成真实用户 IP,需启用 http_realip_module 并配置:
-
set_real_ip_from:填写你信任的上游代理网段(如 Cloudflare 回源段、阿里云 SLB 网段100.64.0.0/10、腾讯云 CLB 网段100.125.0.0/16) -
real_ip_header X-Forwarded-For:指定从哪个头里提取原始链路(推荐,兼容多层) -
real_ip_recursive on:逐级剔除可信代理 IP,保留最左边那个非私有、非代理的 IP
配置生效后,$remote_addr 和 $realip_remote_addr 才真正代表用户真实 IP。
再用 proxy_set_header 正确透传
确保上述步骤完成后,在含 proxy_pass 的 location 块中(且必须写在 proxy_pass 之前)添加:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
-
proxy_set_header X-Real-IP $remote_addr:简洁明确,后端可直接读取单值 -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for:自动追加,不覆盖上游已有的原始 IP,适配 CDN/WAF 多级场景
不要写 proxy_set_header X-Forwarded-For $remote_addr,否则会丢失原始链路信息。
后端必须主动读取,不能依赖 REMOTE_ADDR
Nginx 不会改写后端的连接上下文,REMOTE_ADDR(或 req.connection.remoteAddress、getRemoteAddr())始终是 Nginx 的 IP。后端需显式提取 header:
- Node.js(Express):
req.headers['x-real-ip']或req.headers['x-forwarded-for']?.split(',')[0].trim() - Python(Flask):
request.headers.get('X-Real-IP') - PHP:
$_SERVER['HTTP_X_REAL_IP'] - Java(Servlet):
request.getHeader("X-Real-IP")
注意:X-Forwarded-For 是逗号分隔字符串(如 203.0.113.1, 198.51.100.2),最左才是用户真实 IP。
验证是否真正生效
快速检查三处是否一致:
- Nginx access_log 中
$remote_addr是否为公网用户 IP(需配合 real_ip_module 日志配置) - 响应头中加
add_header X-Debug-Real-IP $remote_addr,看浏览器开发者工具 Network 面板返回值 - 后端打印
X-Real-IP和X-Forwarded-For头内容,确认非内网地址、非127.0.0.1










