要让后端获取真实客户端ip,必须同时满足nginx透传、信任链路识别和后端主动读取:配置x-real-ip与x-forwarded-for头,限定可信代理网段并启用real_ip_module解析,后端需显式读取对应header而非remote_addr。

必须配齐的两个 IP 头
只设一个头容易出错,推荐同时配置:
-
X-Real-IP:设为
$remote_addr,简洁明确,后端可直接读取 -
X-Forwarded-For:用
$proxy_add_x_forwarded_for,不是$remote_addr——它会自动保留上游已有的值,并在末尾追加当前层真实 IP,适配 CDN、WAF 等多级代理场景
必须限定可信代理来源
如果 Nginx 前面还有 CDN、SLB 或其他代理(比如 Cloudflare、阿里云 WAF),$remote_addr 实际是它们的出口 IP,不是用户真实 IP。此时仅靠 header 会被伪造。
需配合以下指令,让 Nginx 主动“解包”出最左真实 IP:
-
set_real_ip_from 203.205.0.0/16;(替换成你实际的可信代理网段,如 CDN 回源段) -
real_ip_header X-Forwarded-For;(或X-Real-IP,取决于上游怎么传) -
real_ip_recursive on;(逐级剔除可信代理 IP,留下最左边的原始用户 IP)
启用后,$remote_addr 和 $realip_remote_addr 就变成真实客户端 IP,后续 proxy_set_header X-Real-IP $remote_addr 才真正有效。
后端必须显式读取,不能依赖 REMOTE_ADDR
Nginx 只负责把 IP 写进 header,后端框架默认仍返回连接方地址(如 Java 的 getRemoteAddr()、Node.js 的 req.connection.remoteAddress)。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
你得手动从 header 提取:
-
Node.js(Express):
req.headers['x-real-ip']或解析x-forwarded-for最左非私有 IP -
Java(Servlet):
request.getHeader("X-Real-IP") -
Python(Flask):
request.environ.get('HTTP_X_REAL_IP') -
PHP:
$_SERVER['HTTP_X_REAL_IP']
注意:X-Forwarded-For 可能是逗号分隔的多个 IP(如 203.0.113.1, 198.51.100.2),最左边才是用户真实 IP,右边是各级代理节点。
额外建议:让 Nginx 日志也记录真实 IP
如果希望 access_log 里直接显示用户真实 IP(而不是 127.0.0.1 或代理 IP),需启用 real_ip_module:
-
set_real_ip_from 127.0.0.1;(仅信任本机反向代理) real_ip_header X-Real-IP;real_ip_recursive on;
这样日志中的 $remote_addr 就是真实 IP,无需再从 header 解析。










