1. 本文场景
这里以我自己的结构为例:
访客→CDN 边缘节点→WAF→Origin Nginx
2. X-Forwarded-For(XFF)介绍
2.1 什么是 XFF?
X-Forwarded-For
(XFF)请求标头是一个事实上的用于标识通过代理服务器连接到 web 服务器的客户端的原始 IP 地址的标头。
——X-Forwarded-For - HTTP | MDN
简单来说,就是用于多层反代之间传递真实的用户 IP。
一下简称 X-Forwarded-For 为 XFF。
2.2 XFF的格式及原理
这种请求头格式并没有多么难以理解,一般为一下这种:
X-Forwarded-For: client, proxy1, proxy2
名词解释:
Client
——客户端Proxy1
——第一层代理Proxy2
——第二层代理
XFF 会由左向右添加记录各级代理的 IP。
例如,在这里,我的 CDN 边缘节点 IP 是 1.1.1.1,WAF IP 是 2.2.2.2,访客 IP 是 3.3.3.3,那么最终源站将会得到这样的 XFF 请求头内容:
X-Forwarded-For: 3.3.3.3, 1.1.1.1, 2.2.2.2
这样,若是源站取其中 3.3.3.3 为访客 IP,即可获得真实 IP。
3. 源站配置
我们首先确保 CDN 会传递 XFF给上游,WAF 也通过 XFF 获取真实 IP 并传递给上游(本例子中为源站 NG)
随后,可以在源站修改 web 服务端配置文件。
3.1 修改 Nginx 配置文件
在 http 块加入以下代码:
http{
......
set_real_ip_from CDN 边缘节点 IP;
set_real_ip_from WAF IP;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
......
代码解释:
set_real_ip_from CDN
边缘节点 IP——声明CDN服务的IP地址为可信代理。只有来自该IP的请求,Nginx才会处理X-Forwarded-For头。若CDN未在可信列表,Nginx会将其视为客户端IP,导致获取错误。set_real_ip_from WAF IP
——声明WAF(Web应用防火墙)的IP为可信代理,原理同上。real_ip_header X-Forwarded-For
——指定从X-Forwarded-For
请求头中提取原始客户端IP。real_ip_recursive on
——从右至左遍历X-Forwarded-For
中的IP,跳过所有可信代理IP,首个非可信IP即为客户端真实IP。
注意:
Nginx 会从右往左读取 IP,直到读取第一个不在 set_real_ip_from
中的 IP 为止。
所以,在 set_real_ip_from
行中,请务必囊括您整条代理流程中的所有 代理 IP(或 IP 段),否则可能会导致源站无法正常解析出真实 IP。
这里放出一个错误示范:
http{
......
set_real_ip_from WAF IP;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
......
可以看到,这个配置文件中仅仅将 WAF IP 添加到了列表中,而没有添加 CDN 边缘节点的 IP。由于 2.2 段中提到的 XFF 工作原理,Nginx 会在从右往左取 IP 时,把 CDN 边缘节点 IP 错误地解析为真实 IP。
X. 版权申明
- 本文作者:Akira(光 · 昭)
- 版权申明:所有文章除特别声明外均系本人自主创作,转载及引用请联系作者,并注明出处(作者、原文链接等)。请在关于页面查看本站采用的版权协议。
- 本文链接:https://www.pyrzo.com/posts/how-to-use-x-forwarded-for
- 封面来源:#原神 【镜中神,戏中人】芙宁娜&芙卡洛斯 - 拾八菌的插画 - pixiv
Comments 2 条评论
这个是不是对源站走cloudflare cdn的站点没用
@fishcpy CF 可以尝试 CF-Connecting-IP 这个标头,多层的话把这个 CCI 一层层传递下去即可。
)
(说句题外话,其实 XFF 大部分情况下不如 X-Real-IP 灵活