发布于 ,更新于 

从山西联通到组播IP:七牛云的奇怪视角(附分析和后日谈)


在本文发布时,作者已经在工单渠道反馈过该问题。

对于任何想要迅速获取事件详情的读者,请直接拉到最后看技术总结
想要看热闹获取更多细节的读者,请继续往下阅读。


起因

他只需略微出手,就能让你 CDN 里的一个小文件一天之内被「五湖四海」访问破万次。
再给他一个神仙管理端,他能让你的 CDN 配置下发延迟近一倍,享受字(liu)节(liang)跳动的快感。

不是代理 IP 买不起,而是伪造 Header 更有性价比。
对此,五星上将麦克阿瑟曾这样评价:「早知道七牛云有这样的科技,我何必去各个注册局购买稀缺 IP。」
大型纪录片《七牛云传奇》持续为您播出。

时间重新倒转到两天前。早就听说有山西联通的 PCDN 团伙为了均衡上传下载量,在搞恶意刷量的行为,从高校镜像站刷到大网站,从大网站刷到小网站。

对于这事尚不明晰的读者,可以看看下面几个链接:

然后不出意外地,前天收到告警,去七牛云一看,刷流量的风还是吹到了我身上。

本来寻思是加个黑名单就完事的运维,没想到成了延续到现在的奇葩事。

并不成功的封堵尝试

上线之后,看了看被刷的 IP,是我博客之前的一个插图,约 500kB 大。

这个 CDN 后面连着的是七牛自己的一个存储桶,这个文件并不是里面最大的,但确实可能是公开途径下能找到的,相对较大的文件。

被刷了怎么办,先学上面几篇博文,加了这么些 IP:

1
2
3
4
5
6
7
8
9
10
11
12
221.205.168.0/23
211.90.146.0/24
122.195.22.0/24
118.81.184.0/23
124.163.207.0/24
124.163.208.0/24
183.185.14.0/24
36.35.38.0/24
60.221.195.0/24
60.220.182.0/24
61.160.233.0/24
60.221.231.0/24

加完之后页面的提示大约是这样的:

然后,15分钟过去了, 这个条依旧没有动的迹象,回去统计一看,又被多刷了约 20G。

后续去查了下系统日志中两个域名的配置执行时间,好家伙,一个比一个重量级:

无奈,只能交个工单催了,然后就出现了以下一幕。

好了,第一个前端看不到的功能出现了。

因为现在的流量好像根本没拦住,所以我便让技术直接下线了 CDN,然后去 DNS 那里停掉了解析。

另一方面的补偿,技术说等商务上班再同步,至此工单一环暂时结束。

封堵基本上是做到了止损状态,可以说是刚好把余额带资源包消耗地差不多,没房子倒是不至于,可以安心跑路。

日志研究

因为可以限制 QPS,我去后台统计分析下了份日志,打算研究一下。

却发现,按照 QPS 来限制根本不可能。

Source IP Status Time
53.165.228.176 HIT [23/Jul/2024:21:00:10
53.165.228.176 HIT [23/Jul/2024:21:00:10
53.165.228.176 HIT [23/Jul/2024:21:00:10
81.13.198.177 HIT [23/Jul/2024:21:00:10
53.165.228.176 HIT [23/Jul/2024:21:00:10
53.165.228.176 HIT [23/Jul/2024:21:00:10
81.13.198.177 HIT [23/Jul/2024:21:00:11
81.13.198.177 HIT [23/Jul/2024:21:00:11
81.13.198.177 HIT [23/Jul/2024:21:00:11
81.13.198.177 HIT [23/Jul/2024:21:00:11
81.13.198.177 HIT [23/Jul/2024:21:00:11
39.93.235.12 HIT [23/Jul/2024:21:00:11
81.13.198.177 HIT [23/Jul/2024:21:00:11
39.93.235.12 HIT [23/Jul/2024:21:00:12
39.93.235.12 HIT [23/Jul/2024:21:00:12
39.93.235.12 HIT [23/Jul/2024:21:00:12
132.224.75.244 HIT [23/Jul/2024:21:00:12
39.93.235.12 HIT [23/Jul/2024:21:00:12
39.93.235.12 HIT [23/Jul/2024:21:00:12
39.93.235.12 HIT [23/Jul/2024:21:00:12

以上是日志的部分切片,可以看到,日志中的每个IP基本上是1s之内发送约10次请求,之后立即轮换到别的 IP.

而这个 CDN 主要用作网页的静态资源加载功能,按照 1s 10次 的策略进行限制的话,百分百会误杀到正常访问网站的客户。以暂时搬出 CDN 的本站为例,全新渲染一次,便要加载十个以上的 js 和 css(仅包含不方便放在公共静态 CDN 上的魔改文件)。

分析完之后有些好奇,去纯真 IP 库查了查这几个 IP 的来源:

1
2
3
53.165.228.176 - 德国 奔驰汽车
81.13.198.177 - 瑞士
39.93.235.12 - 山东省临沂市 联通

我此刻的内心已经是:哈?

继续翻看日志,一条 IP 映入我的眼帘:

1
0.158.142.12 HIT 60 [23/Jul/2024:21:11:37 +0800] "GET https://cdn./wp-content/uploads/2022/12/ HTTP/1.1" 200 561208 "https://cdn./wp-content/uploads/2022/12/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/419.3 (KHTML, like Gecko) Safari/419.3"

一下就把晚上十点的我干醒了,于是用 Excel 的数据透视表功能去了个重,发现了如下货色:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
0.111.196.55
0.116.60.85
0.144.42.232
0.154.158.185
0.158.142.12
0.177.35.80
0.182.166.156
0.234.236.74
0.252.205.185
0.34.82.77
0.40.251.18
0.52.122.102
0.60.116.133
0.75.211.6
0.8.192.236
0.84.207.198
0.92.183.218
0.93.164.77
1.103.194.250
...
10.1.14.148
10.104.45.33
10.126.42.144
10.164.106.0
10.18.220.123
10.181.176.62
10.182.9.167
10.197.17.132
10.20.104.168
10.238.149.150
10.249.26.29
10.34.112.50
10.48.72.0
10.60.61.114
10.71.43.19
10.8.220.210
10.82.138.113
10.9.178.252
10.96.71.60
100.153.101.189
100.154.41.99
100.184.125.18
100.215.147.100
100.242.101.30
100.245.117.202
100.249.21.122
100.27.239.17
100.39.93.28
100.59.203.6
100.70.141.101
101.111.3.65
101.128.82.159
101.130.240.252
101.133.124.76
101.169.35.8
101.207.76.136
101.215.66.131
101.220.92.197
101.223.179.49
101.231.99.114
101.238.124.1
101.254.211.166
101.40.171.194
101.46.48.217
101.74.86.45
101.80.115.130
102.131.48.103
102.156.58.209
102.162.93.243
102.176.161.142
102.19.9.164
102.233.108.173
102.235.74.147
102.247.40.244
102.251.141.14
102.29.115.58
102.74.71.209
102.88.215.31
103.115.169.89
103.143.139.146
103.171.252.70
103.179.245.11
103.197.205.178
103.218.249.175
103.244.158.232
103.4.114.171
103.44.100.29
103.45.21.188
103.75.54.127
104.108.66.143
104.153.174.161
104.155.134.65
104.190.29.135
104.191.130.191
104.220.130.105

好家伙,0开头的IP,内网IP,保留IP齐上阵,一度让我觉得学的网络原理知识还给老师了。

从上到下看,发现IP段从 100 一路轮到了 254.

1
2
3
4
5
6
7
8
254.121.107.22
254.129.171.195
254.135.153.178
254.141.129.153
254.147.194.225
254.192.123.127
254.192.234.110
254.20.230.168

从任何角度出发,我的理智都已经告诉我这些不是正常的 IP,首先的猜想便是:Hackergame 2021 的题目 FLAG 助力大红包 竟然照进了现实。

在此引入该题题解部分内容:

即便没有上面这一步,应当可以很快意识(也许很难)到使用好友助力或使用代理池是不可行的,这是由于不是全部 IPv4 /8 地址块是可用的。这包括:

  1. RFC1700 定义的 0.0.0.0/8 和回环地址 127.0.0.0/8
  2. RFC1918 定义的私有地址 10.0.0.0/8、192.168.0.0/16 ,172.16.0.0/12
  3. RFC3171 定义的组播地址 224.0.0.0/4
  4. RFC1700 定义的保留地址 240.0.0.0/4
  5. 用于特殊网络的 14.0.0.0/8 , 24.0.0.0/8 以及 39.0.0.0/8
  6. 美国国防部宣告的大量 IPv4 /8 网段,例如 6.0.0.0/87.0.0.0/8 等等 十几个 /8 网段

详细信息可参考 RFC3330.

此时七牛后台的日志分析长这样:

我把我的疑问发在工单里,得到了技术这样的回复:

七牛的后台里,黑白名单数量只能添加500条,如果真的把这些「轮段」IP按技术所说的加入黑名单,先不说是不是还会被卡住,保底也得把整个互联网完全封掉。

就在此时,伟大的技术工程师掏出了前端没有的第二个功能。

这明显无法解决问题的根源。我要求将问题上报,技术回复等明天上班时间。加之 CDN 的实际消耗需要等第二天8点才能出账,无奈只好先放下这事,睡觉。

对线?

时间拨到第二天:没睡好。

醒来之后看了看用量统计,还好,没破产。

但此时的问题转向了:先前的日志统计里绝大部分都是海外IP,为什么在这里抵扣的却是中国大陆资源包呢?

晚些时候,商务的电话打过来了,我把问题重新和他理了一遍,他表示会同步给技术,然后就收到了技术这样的回复。

好吧,第三个前端看不到的功能出现了。

此时此刻,技术明显没有理解我的意思,麻烦了商务老师,我要求和他重新同步我的疑问。

之后便是包括工单和400电话的对线垃圾时间,来回太过冗长,此处仅展示七牛云方面的信息:

  1. 页面标记的「配置8-15分钟」只是预估。实际无法为此提供任何担保。当发现配置超时时用户须提交工单让人工介入。
  2. 日志里标记海外但是却消耗国内资源包,是因为海外访问到了国内的IP。

从道理上这些都能理解,但是这一切的一切显然都是建立在 IP 来源统计正确的情况下。

我没受过严格的训练,我不知道他看到「未知」来源消耗了10多G流量以及日志中0.开头的IP时,怎么能忍住不笑的。

真相大白

后来,我发现工单技术从后台导出的日志似乎比我前台下到的详细得多,就让他导出了一份23号的日志,就是昨天0.开头IP现场的日志。

拿到日志后,我发现一切真相大白。

详细的日志分析

此部分希望能成为其他站长防御的参考。

首先来看 UA 部分:

ua
Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/125.5.6 (KHTML, like Gecko) Safari/125.12
Mozilla/5.0 (iPad; CPU OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/10.0.649.0 Safari/534.17
Mozilla/5.0 (iPad; CPU OS 9_3 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13E230 Safari/601.1
Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16A366 Instagram 65.0.0.12.86 (iPhone7,2; iOS 12_0; es_CO; es-CO; scale=2.00; gamut=normal; 750x1334; 125889668)
Mozilla/5.0 (iPhone; CPU iPhone OS 12_0_1 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) GSA/60.0.215960477 Mobile/16A404 Safari/604.1

能够看到基本上是随机的 UA ,除基本特征外与浏览器和设备相关的数字都经过了随机化,基本不可能拦截。

Referer 部分和原 CDN 链接相同,设置「空 Referer」拦截并不能成功避免,设置泛域名更不行。

这些都是小菜,直到看到了 X-Forwarded-For 列后,我释然了:

最右边谁啊,60.221 开头,这不就是臭名昭著的山西联通 IP 段嘛。

很明显,此处通过伪造 XFF 的请求头,实现了伪造 IP 的目的,并进一步欺骗到了七牛的系统。

最后

省去一大截沟通流程,有效信息如下:

  • 七牛的策略认后面的 client_ip ,即被伪造的 IP。(IP黑白名单可能也是认这个 client_ip ,但我没有确认*)
  • 七牛方面依旧是建议使用 CPS 、限速限制、或者封堵海外访问。对于 X-Forwarded-For 请求头这个问题,七牛方面暂无解决方案,建议我使用回源鉴权功能。

*最后的最后,可能有读者会有疑问:说的那么玄乎,为什么不亲手验证下呢?

说得好,我也想。本着报道要讲事实的原则,我把自己的 IP 段扔进了另一个·域名的黑名单,想要实地模拟一下享用 0. IP的感觉。

我从开始写这篇文章的时候加上了请求,截至我写到现在,系统的自动配置仍未完成。

技术总结

  • 可能因为 XFF 欺骗漏洞,七牛 CDN 对于客户端 IP 的判定有非常大的问题,这会导致日志中的 IP 信息可被轻易伪造,并有可能进一步影响 IP 黑白名单配置
  • 发现 CDN 配置超出页面显示的时间后,务必去工单催一下。
  • 七牛 CDN 有些限流功能并未在前台展现,包括基于 QPS 的封禁、全站带宽限速、阻断境外访问,这些功能需要通过工单申请。

*标注可能的原因是我不了解真实的情况,或者不方便验证,不对相关言论负责。

第三天醒来的事

博客文章被转出去,溜 v2ex 的过程中看到了这么一篇:公司的阿里云 CDN 每晚都在被偷偷刷量

几乎拿了完全一样的剧本:奇怪的IP、工单的顾左右而言他。

这篇文章导向了阿里云的一个帮助文档:https://help.aliyun.com/zh/cdn/user-guide/download-logs

该文章里直球表示了,我们日志里拿 IP 就是取 XFF 第一个。

这里想要拿到真实IP,按原帖的说法,只能使用远程鉴权和实时日志功能,人力成本不可谓不高。

上回中已经详细分析了,只要 XFF 是伪造的,该种判断逻辑就没有任何意义

从 v2ex 的发布时间来看,这次攻击从两个月前就开始了,因此如果阿里云/七牛云的防护是通过判断完整的 XFF 完成的,那也是可以防护的。

一切的一切,还是建议给CDN上个告警防护,阈值设低点早发现比什么都强。

另外都到这一步那必须得测测了,楼上的那个测试域名到现在还没配置好,让我去借个号再回来。