X-Forwarded-For 是什么?经过 Nginx 和 CDN 后,怎样获取真实客户端 IP?
下面是一段教学模拟,不是真实面试记录。
🧑💻 面试官:请求经过 CDN 和 Nginx,你怎么取客户端 IP?
🙋♂️ 我:读取 X-Forwarded-For 的第一个地址。
🧑💻 面试官:用户自己填了这个头,第一个地址是他伪造的呢?
🙋♂️ 我:那要相信代理写入的部分。
🧑💻 面试官:哪台代理可信,你怎么知道?用户绕过 CDN 直接访问源站,又该怎样处理?
“最左边就是客户端”需要前提。真正要判断的是「可信代理在哪里结束」,不能把用户提交的字符串直接当成安全依据。
面试速答(60 秒版)
X-Forwarded-For 记录请求经过代理时的地址信息,但它本身可以被客户端伪造。
获取用于安全判断的 IP,先检查当前连接是否来自可信代理,再根据部署约定解析代理链。采用可信代理列表时,通常从右向左跳过可信代理,取第一个不再属于可信代理的地址;它可能是用户使用的另一台代理,不一定是设备本身。
同时要防止源站被绕过,并确认 CDN 和 Nginx 怎样清理或追加这个头。
最终,IP 只能作为网络来源信息,不等于用户身份。限流和审计可以使用它,但授权仍需要登录与业务权限,不能只相信某个头字段。

知识点详解:应用看到的连接,和用户最初的连接不一样
直接连接只知道上一跳
假设请求路线是浏览器 → CDN → Nginx → 应用。
应用的直接连接对端是 Nginx,不是浏览器。要知道更前面的来源,需要由代理转交信息。
X-Forwarded-For 常见约定是将地址按链路追加。但“常见约定”不意味着客户端不能自己提供初始内容,也不意味着每家 CDN 都使用完全相同的清理规则。MDN 安全说明
用一条伪造链看看为什么不能取最左边
假设用户连接地址是 203.0.113.10,却自己提交:
X-Forwarded-For: 198.51.100.99
可信入口追加它实际看到的来源,后续可信代理继续转交。应用最后看到的链里,最左边仍可能保留伪造值。
因此,直接取最左边,就可能把用户想让我们相信的地址当成事实。所有地址都是教学保留地址,不对应真实用户。
采用可信列表策略时,从实际连接对端开始确认信任,再沿完整链从右向左检查,越过我们明确控制或信任的代理,在第一个非可信位置停止。不要继续越过这条边界寻找一个“更像公网”的地址。

可信头需要可信入口
如果外网能直接访问源站,用户就可能跳过 CDN 的清理过程,自己发送一组看似正确的头。
因此需要限制入口或在直连场景不信任转发头,并明确各代理只信任哪些上游。
Nginx 的 realip 模块提供可信来源与解析相关配置,但配置值来自实际网络拓扑,不能随便写“信任所有 IP”来让测试通过。Nginx 官方文档
还要考虑多个同名头、非法内容与 IPv6。应使用经过验证的解析机制,按完整列表处理,不是简单取一个字符串再用冒号分割。

拿到可信网络来源,也不等于拿到用户身份
多个用户可能共享 NAT 出口,一个用户也可能频繁改变网络或通过代理访问。
所以限流需要按目标结合 IP、登录用户、业务对象等维度,避免把共享出口下所有用户混成一个人。
更不能仅靠 IP 决定能否修改订单或读取私有资料。地址用于辅助风险判断,身份和对象权限依然需要独立验证。
面试官继续追问
Forwarded 是标准头,就可以直接相信吗?
不能。标准化描述格式,不会自动验证是谁写入。它同样需要可信代理与入口边界。
信任固定代理数量,和信任代理地址一样吗?
不是。数量策略依赖路线长度稳定;存在短路或不同路径时可能不安全。列表策略依赖地址范围准确,两者都必须匹配部署。
为什么日志 IP 正确,限流还会被绕过?
日志可能使用另一个解析逻辑,限流则读取原始头。应统一可信来源规则,并测试伪造、直连和多代理路径,而不是只检查一条正常请求。
面试速记卡
- XFF:转交代理链来源信息,但客户端也可以伪造。
- 第一判断:当前连接对端是否为可信代理。
- 列表策略:从右向左越过可信代理,在首个非可信边界停止。
- 部署要求:防止绕过入口,确认清理、追加与解析规则。
- 身份边界:可信 IP 是网络来源,不是用户授权凭证。
公司面试真题
这道题暂未收录可核验的公司真题来源。你可以先阅读本文解析,或浏览已收录的公司面试真题。
浏览公司面试真题 →