要让后端获取真实客户端IP,需在Nginx中配置proxy_set_header透传X-Real-IP和X-Forwarded-For,并在多层代理时用set_real_ip_from指定可信代理网段、real_ip_header指定来源头,最后后端须主动读取对应Header而非request.getRemoteAddr()。

在Nginx作为反向代理时,默认情况下后端服务(如应用服务器)收到的请求IP是Nginx所在机器的内网IP,而非用户真实IP。要让后端获取真实客户端IP,需配合proxy_set_header指令透传关键IP字段,并确保后端正确读取这些Header。
关键Header设置:X-Real-IP 和 X-Forwarded-For
Nginx本身不自动识别“真实IP”,需手动指定哪些请求头用于传递客户端地址:
- X-Real-IP:通常设为客户端最原始的IP(单个值),适合后端直接信任并使用
-
X-Forwarded-For:标准HTTP扩展头,记录经过的代理链路,格式为
X-Forwarded-For: client, proxy1, proxy2;Nginx默认用$remote_addr追加,但更安全的做法是显式覆盖或继承
推荐配置示例(放在location或server块中):
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; # 若上游已有X-Forwarded-For(如前面还有CDN),可用以下方式追加而非覆盖: # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
处理多层代理(如CDN + Nginx)
当用户请求经过CDN、WAF或多个Nginx节点时,$remote_addr只是上一跳代理的IP,不能代表真实用户。此时需依赖CDN注入的Header(如X-Forwarded-For或X-Real-IP)来还原源头IP。
安全做法是:只信任可信代理(如CDN出口IP段),从其传来的X-Forwarded-For中提取最左/最右非私有IP:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- 启用
set_real_ip_from指定可信代理网段(如CDN IP段) - 设置
real_ip_header X-Forwarded-For;或real_ip_header X-Real-IP; - 启用后,
$remote_addr将自动变为解析出的真实客户端IP,后续proxy_set_header可直接使用
示例(假设CDN出口IP为203.205.0.0/16):
set_real_ip_from 203.205.0.0/16; real_ip_header X-Forwarded-For; real_ip_recursive on; # 允许递归查找,取最后一个非私有IP
后端服务必须主动读取对应Header
Nginx透传只是第一步,后端应用(如Node.js、Python Flask、Java Spring)默认仍读request.getRemoteAddr()或req.ip——这些返回的是Nginx连接IP,不是真实IP。
需在代码中明确读取Nginx设置的Header:
- 优先检查
X-Real-IP(单一可信值) - 或解析
X-Forwarded-For,取最左侧非私有IP(注意防伪造,需结合可信代理白名单) - 部分框架支持配置(如Express用
app.set('trust proxy', true)自动处理)
验证是否生效
可在Nginx日志中临时添加真实IP字段确认:
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'X-Real-IP:$http_x_real_ip X-Forwarded-For:"$http_x_forwarded_for"';
然后访问接口,查看access.log中X-Real-IP和X-Forwarded-For是否为你的公网IP;再检查后端打印的request.getHeader("X-Real-IP")是否一致。

















