X-Real-IP 是什么
X-Real-IP 是 Nginx 生态里常用的自定义请求头,只放一个客户端 IP,也就是最后一跳代理认定的真实来源地址,比 X-Forwarded-For 那样的一串列表更好解析。它没有 RFC 定义,属于约定俗成的做法:反向代理在转发请求时把 $remote_addr 写进这个头,后端应用直接读取即可拿到访问者地址。因为它只是「一个字符串」,来源不可信时必须由边缘代理覆盖,而不是信任客户端自行传入的值。
基本信息
| 名称 | X-Real-IP |
|---|---|
| 规范 | 无 RFC,属 Nginx/fastcgi 生态约定 |
| 作用 | 传递单个真实客户端 IP |
| 对比 XFF | X-Real-IP 是单值,X-Forwarded-For 是链 |
| 可信前提 | 仅信任由自己控制的边缘代理写入的值 |
| Nginx 模块 | ngx_http_realip_module(set_real_ip_from / real_ip_header) |
典型使用场景
- 应用需要记录访问者 IP,但请求经过 Nginx 反向代理后 $remote_addr 变成代理地址
- 在前端做 IP 白名单或限流,需要拿到真实来源地址
- 日志分析、风控规则依赖客户端 IP 时,统一从该头取值
- 多层代理架构下统一约定取值口径,避免各层各写一个头
- 与 XFF 并存时确定优先级,由团队约定只取其一
透传真实 IP
透传真实 IP
# 边缘代理:覆盖写入,防止伪造段混入
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://backend;
}
# 若 Nginx 自身需要把上游代理地址还原成真实客户端
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Real-IP;
real_ip_recursive on;
# 验证
curl -sI -H 'X-Real-IP: 1.2.3.4' https://example.com/ | head -1与 XFF 的取值对照
| 场景 | X-Real-IP | X-Forwarded-For |
|---|---|---|
| 单层代理 | 最后认定的客户端 IP | 列表首项为客户端 IP |
| 多层代理 | 视最后一跳写法,可能只有一跳 | 逐层追加,需要取可信段 |
| 取值难度 | 单值直接可用 | 需处理空格与逗号、剔除伪造段 |
| 伪造风险 | 客户端可自带,须由边缘覆盖 | 同样可被追加伪造 |
| 标准程度 | 非标准约定 | 广泛使用的事实标准 |
客户端可以自己发一个 X-Real-IP 请求头,如果边缘代理不覆盖而是原样透传,后端记录的「真实 IP」就是攻击者随便填的。可信做法是边缘代理一律覆盖写入,并只信任来自已知代理网段的值,绝不无条件相信外部输入。
后端同时拿到 X-Real-IP 与 X-Forwarded-For 时,按团队约定固定取一个,并写死在公共中间件里;取值口径散落在各处代码中,往往会出现「不同接口记录到不同 IP」的数据不一致问题。