长亭百川云 - 技术讨论

长亭百川云

技术讨论长亭漏洞情报库IP 威胁情报SLA在线工具
热门产品
雷池 WAF 社区版
IP 威胁情报
网站安全监测
百川漏扫服务
云堡垒机
百川云
技术文档
开发工具
长亭漏洞情报库
网安百科
安全社区
CT STACK 安全社区
雷池社区版
XRAY 扫描工具
长亭科技
长亭科技官网
万众合作伙伴商城
长亭 BBS 论坛
友情链接
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备2024055124号-2

利用CDN自定义请求报头功能实现源站精确获得访客ip

发布于 6 个月前

# 雷池 WAF
# 雷池技术博客投稿

发布于 6 个月前

头像

风熙.

更新于 6 个月前

0

0

雷池技术博客投稿

提要

该文章同时在我的博客网站刊载,欢迎光临
本文适用情况:用户第一层访问的是CDN,或者是其他可以添加自定义HTTP请求头的,而且代理链路可信不会修改你的自定义请求头,这个方法不论有没有使用雷池,是通用的。

按照本文教程配置成功后可以实现“一头走天下”:只要代理链路不对自定义头修改,任何代理链路和源站都可以直接读取这个头获得访客ip,而不需要繁琐的配置XFF

不想看长文的直接跳转到正片


最近我看到有些同学们配XFF出现了很多问题,依照我早期摸索出的经验,写下这篇文章。

基础知识

什么是HTTP请求体

HTTP请求体由三部分组成:请求行、请求头、报文体。

这是一个正常的的HTTP请求

HTTP请求示例

其中,第一行的①、②、③统称为请求行;报文头也称为请求头

可以看到,一个正常的HTTP请求带有这些参数,接下来我将通过访问哔哩哔哩网站并抓包来详细讲解。

HTTP请求示例2

在这个请求体示例中,由于是用的GET方法进行请求,GET请求方法是指:向服务器发出请求,意图从服务器下载东西。因此不含有报文体。

可以看到,在我访问哔哩哔哩的请求头中,我使用HTTP/1.1协议通过GET方法向服务器发出请求;在User-Agent栏,也就是我们熟称的浏览器UA中可以看到,我正在使用版本号为537.36的电脑版Edge浏览器进行访问,这个浏览器的内核是Chrome136.0.0.0,一些手机浏览器访问电脑版网页也是通过伪造浏览器UA来实现。

什么是X-Forward-For

X-Forwarded-For 是相对通用的 HTTP 请求头。

当CDN部署在最外层,HTTP 流量是经过CDN进行代理传回的,由于网络连接被CDN截胡,源站服务器无法得知真正的客户端 IP。

这时代理设备(CDN)会给当前的流量加上一个 X-Forwarded-For 头,里面的内容就是连接这个代理的客户端 IP。

下面这个例子中 HTTP 代理通过 X-Forwarded-For 头告诉服务器,真正的客户端地址是 1.2.3.4

1GET / HTTP/1.1
2Host: example.com
3User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36
4X-Forwarded-For: 1.2.3.4

X-Forwarded-For 实际上是一个链式结构。如果流量经过了多层代理设备,X-Forwarded-For 会记录途径的所有 IP。

下面这个例子中 HTTP 代理通过 X-Forwarded-For 头告诉服务器,流量经过了三层代理,真正的客户端地址是 1.2.3.4。

第一层代理的是 11.12.13.14,第二层代理的地址是 21.22.23.24,第三次代理的地址可以直接通过网络连接获取。

1GET / HTTP/1.1
2Host: example.com
3User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36
4X-Forwarded-For: 1.2.3.4, 11.12.13.14, 21.22.23.24
  • 从网络连接中获取: 当雷池作为最外层代理设备,无其他前置代理时选用

  • 从 X-Forwarded-For 中获取上一级代理的地址:在流量到达雷池之前还有一层代理设备(如 Nginx,CDN 等)时可选用

  • 从 X-Forwarded-For 中获取上上一级代理的地址:在流量到达雷池之前还有两层代理设备(如 Nginx,CDN 等)时可选用

  • 从 X-Forwarded-For 中获取上上上一级代理的地址:在流量到达雷池之前还有三层代理设备(如 Nginx,CDN 等)时可选用

  • 从其他 HTTP Header 中获取

    :有几种情况

    • 流量经过了一些特殊的反向代理设备,这类代理不会发送 X-Forwarded-For 头,但是可以通过配置,把 IP 通过其他头发过来
    • 流量到达雷池有多种途径,可能有一层代理,也可能有两层代理,可以通过配置前置代理设备来统一 HTTP 头

问题

X-Forward-For的链式结构会带来一些问题,比如这位同学

3

这位同学的CDN请求雷池的请求头中,XFF携带的ip数量不等,原因是用户的请求头中就有残留XFF报头,有的CDN只会在XFF后面加上直接获取的ip,而不会清空重写,这一般是用户存在代理导致的。

一般来说多的前几个是代理ip,cdn添加的是直接从网络连接获取ip,不是这位同学所说的最左边才是真实ip(当然也可能是代理转发前的ip),因此可以通过从后往前读xff获取cdn从网络连接中直接获取的ip

但是还有什么办法,更通俗易懂、更好配置呢?

X-Real-IP

有的同学说,X-Real-IP不会被伪造,经我测试,在一些存在漏洞的CDN中依然可以被伪造,例子如下

第一步,我提前在CDN之前就添加了X-Real-IP请求头,写入阿里云DNS 的ip223.5.5.5。在雷池中配置使用X-Real-IP读取访客ip。

这个请求体中包含恶意元素,将使得雷池WAF将拦截我的请求,便于我观察转发后的流量。

第一步

发包后,雷池拦截

5

可以看到,X-Real-IP并没有被清空重写,而是直接就这样发出去了,我CDN是有开传递X-Real-IP的。

这下不得了了,此时攻击者直接变成了223.5.5.5(阿里云DNS的IP),并且IP 威胁情报-长亭百川云平台甚至可以查到?!

6

阿里云对不起。。。

正片

配置CDN

在CDN控制台中,添加请求报头,报头名称你可以自定义,这里我使用X-Real-Forwarded-For作为我自定义的请求报头。

值填${rawRemoteAddr},意为CDN通过网络连接直接获取的ip地址。

7

配置雷池

没有装雷池的可以直接往下看,由于自定义报头不存在链式结构,因此每一层都可以直接通过这个头获得ip。

在雷池——防护应用——高级配置中的源IP获取方式中,设置从HTTP Header中获取,值填你自定义的请求报头。

9

配置源站

在你的Nginx配置文件中加入以下配置

set_real_ip_from 0.0.0.0/0;
real_ip_header X-Real-Forwarded-For; #填你自定义的请求头 

记得要在前面加两个缩进

10

然后保存

测试

对我的博客进行模拟 SQL 注入攻击并抓包,如何测试防护效果请翻阅雷池官方文档:测试防护效果 | 雷池 SafeLine

11

可以看到被拦截了,返回了403,我们回雷池看一下日志

12

可以看到被雷池拦截了,请求报文中带有我们自定义的X-Real-Forwarded-For,记录了我的真实ip。

接下来我进行请求重放,在用户端就伪造这个请求头,模拟这个请求头被黑客知道了的情况

一般别人不可能知道我们自定义的请求头,因为这个请求头只在CDN和雷池(或源站)之间通信,不对外发送和开放。但是为了确保严谨性,我还是进行请求重放测试

13

我自己手动添加了一个自定义的请求头,模拟被黑客知道然后伪造请求头攻击的情况。

可以看到被雷池BYPASS,回到雷池日志看看情况

15

可以看到自定义请求头仍然被替换成了访客的真实ip,也就是说通过伪造请求头骗过源站的方式不凑效了。

这样,我们实现了一头走天下:只要代理链路不对这个头修改,任何代理链路都可以直接读取这个头获得访客ip,而不需要繁琐的配置XFF。

答疑

为什么我的宝塔面板同时出现雷池和访客的ip?(如下图),为什么日志有时候会显示在访问null

16

答:因为你在雷池启用了上游服务器健康检查,显示访问路径null是因为包雷池拦了

解决方法:在雷池面板防护应用的应用详情中,点基本信息——基础配置右边的笔,关掉上游服务器健康检查。

2025年6月14日17:11:41补充:如果你的cdn可以支持自定义请求报头,那么建议也给X-Forwarded-For加上相同的内容规则以清空重写xff

​
头像
相关贴子
#
建议为社区版本添加深色模式支持
#
希望雷池添加可以生成原服务器域名证书的功能
#
雷池规则广场:拦截常见扫描器
#
certd创建自动化流水线使用letsencrypt申请证书并更新雷池waf证书
#
一个站点,nginx 里面需要多个location不同判断,如何自定义