x-real-ip是nginx约定的单值真实ip头,需在最后一级可信代理设置并配合set_real_ip_from等指令校验;后端须显式读取该头而非remote_addr,并做合法性校验。

在多层代理(如 Nginx → CDN → 负载均衡器 → 应用服务器)环境中,后端服务默认只能拿到最靠近它的上一跳代理的 IP(通常是 CDN 或 LB 的出口 IP),而非用户真实 IP。要还原真实客户端地址,关键在于逐层传递并最终信任 X-Real-IP 或 X-Forwarded-For 头,而 proxy_set_header X-Real-IP 是 Nginx 主动设置该头的核心指令。
理解 X-Real-IP 与 X-Forwarded-For 的区别
X-Real-IP 不是标准 HTTP 头,而是 Nginx 社区常用约定,用于**单值传递最可信的真实客户端 IP**;X-Forwarded-For 是标准头,以逗号分隔多个 IP(如 X-Forwarded-For: 203.0.113.5, 192.168.10.20),但易被伪造,需结合可信代理列表过滤。
使用 X-Real-IP 更简洁安全——前提是只在**最后一级可信代理(如边缘 Nginx)上设置它**,且确保上游不会重复添加或篡改。
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
在 Nginx 中正确配置 proxy_set_header X-Real-IP
必须在 location 或 server 块的 proxy_pass 上游转发配置中设置,且优先级高于默认行为:
- 用
$remote_addr设置:适用于 Nginx 是最外层代理(直接接收客户端连接),此时它就是真实 IP - 用
$http_x_forwarded_for设置:适用于 Nginx 本身在中间层(如内网负载均衡),需从上游X-Forwarded-For中提取最左/最可信 IP - 务必配合
set_real_ip_from和real_ip_header指令启用真实 IP 解析,否则$remote_addr不会更新,$http_x_forwarded_for也可能不可信
确保上游代理链可信并避免伪造
X-Real-IP 的有效性完全依赖于“谁设置了它”和“谁信任它”。若任意中间代理可随意写入,该头就毫无意义:
- 仅允许已知可信代理 IP(如 CDN 回源 IP 段、公司 LB 内网地址)通过
set_real_ip_from声明为可信源 - 用
real_ip_header X-Forwarded-For配合real_ip_recursive on,让 Nginx 自动剥离可信代理 IP,取剩余最左非可信段作为真实 IP - 禁止公网用户直接访问后端 Nginx,防止绕过首层代理伪造
X-Real-IP
后端应用如何安全读取真实 IP
即使 Nginx 正确设置了 X-Real-IP,后端代码仍需明确信任该头而非 REMOTE_ADDR:
- Node.js(Express):
req.headers['x-real-ip'] || req.ip,并确保 Express 启用了trust proxy - Python(Django):配置
USE_X_FORWARDED_HOST = True和SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),再通过request.META.get('HTTP_X_REAL_IP')获取 - Java(Spring Boot):需启用
server.forward-headers-strategy=framework,并确认反向代理配置了X-Forwarded-For和X-Forwarded-Proto - 始终校验 IP 格式合法性,拒绝非法字符串(如注入空字节、换行符)










