记一次流量攻击(traffic attack, DDoS)的解决过程

Posted by NosaLee in UNIX/Linux, Web Programming & Resources on 21-02-2020.

20200219 本是产品促销的好日子,但很不幸也引来了流量攻击。

具体表现就是攻击者疯狂下载网站上的较大资源(如 .zip .exe )以消耗流量,大约 30 MB/s(自己下美剧也有这么快该多好 )。

环境:Linode + 宝塔面板 7.0.1 + CentOS 7.6 + Apache 2.4.41 + MySQL 5.6.44 + PHP 7.3 + CloudFlare(CF) CDN

发现攻击开始的几小时内网站和内心都很乱,因为同时面临着若干问题

1、流量即将耗尽,本月还有 1/3 的时间怎么办?

2、问题 1 能解决,先将 Linode 扩容就好了,但扩容的关机、resize、开机等操作也是需要好几分钟时间的,正在促销,万一就在这几分钟内用户要下单则会造成直接经济损失。

3、用了 CF,在 OS 里用 netstat 就只能看到 CF 的 IP(s),而看不到攻击者的 IP(s),这又该怎么办?

4、问题 3 也能轻松解决,先关闭 CF 代理就好了。然而问题 2 面临的尴尬又出现了:关闭 CF 代理后本站主机 IP 对终端访客来说就变了,DNS、本站服务器、用户 ISP / LAN / 终端 OS / 浏器器的缓存问题会导致网站不能正常访问时间更长。另外因为促销,正常 IPs 也较多,抓出流氓也并不是那么容易——分析大量 netstat 输出会让人头更大。

5、大量的带宽及资源占用也直接影响正常用户的访问。

在忙乱中,忍痛也试了 2 和 4 的方法,但还是没解决问题,后来也先把 CF 代理启用了(因为启用后网站访问至少是正常的,还有 Linode 被墙的原因也需要启用)。

就这样毫无头绪地折腾了约 4 小时,意识到操之过急 + 无正确思路会让解决问题所花时间更长。

此时,什么都不做,静下心来理顺思路再有条不紊地实作才是好办法。

经过约 10 分钟的思考,形成了简单但有力的指导思想——找出坏“人”,屏蔽 ta 们。接下来会证明思路是完全正确的。

一、找出坏“人”

1、工具制作

第一件事便是获取访客的原始 IPs,在前 4 个小时的忙乱中,一味去分析 iftop(流量占用命令)、netstat 输出发现并没有用,而 CF 也没有直接提供原始 IPs 查询功能。

Google 吧,“how to find out cloudflare original ip address”,大概有两种方法,一是读 headers、二是在 Apache 里加 mod_* 什么的。

我一般不喜欢为了某个第三方平台去改系统配置(改改网页可以),所以选择了第一个方法。

这个就不列代码了,自己随便搜一下“PHP get headers”,有很多现成脚本可用。

把这些取 headers 的脚本放到一个 PHP 文件里(如:getHeaders.php),自己访问了一下,的确能输出原始 IP,即 Cf-Connecting-Ip 信息。

2、引贼入坑

工具有了,怎么抓坏“人”?ta 又不会直接访问你这个测试脚本!

随意插一句:从上文那 10 钟后,每一步所想所做都完全正确,没有走一点弯路,可能是运气太好。

不直接访问那就让 ta 间接访问,重定向吧!.htaccess 秒秒钟搞定。

但是,重定向的访问源什么呢?——既然能耗掉那么多流量,而我的文件又不大(几百 K),肯定是多个 IPs 多线程访问,那就去看看网站访问日志呗。

tail -f ###.com-access_log

OMG,那神一般的刷屏速度见所未见,要是正常情况真有这么大流量,都不至于纠结 Linode 流量限制问题了,随便攻击,俺有的是带宽、有的是内存、有的是 CPU……

再进一步,tail -f ###.com-access_log | grep .exe,还是疯狂刷屏;Again,tail -f ###.com-access_log | grep test.exe,ta 仍是不知疲累地忙碌着。

但这反而对解决问题非常有利!.htaccess 里重定向 test.exe 到 getHeaders.php 即可抓到 ta 的 IP!

可现实情况远远没有想象中的简单:

这是个很智能的攻击者:测试时为了方便自己查看,直接 echo 了 headers(当然同时也写了文件如 attackers.log,不然怎么看 IP(s),我自己又不是攻击者,看不到浏览器输出),而这会导致攻击者能“看”到输出,当“意识”到自己的身份(IP)已暴露后,会停止攻击 test.exe,转而去下载其他文件。

也就是说 ta 会给反攻击者制造一种假象——这个 IP 是友好的。经测试,如果 echo 了,基本上 ta 访问 3 次就停;但如果没  echo,会一直访问。

 

好吧,你会伪装,那我也伪装吧!全面伪装!将正常页面(如购买页)复制一份(还要像模像样地命名,如 order-now.htm),然后在末尾加上取 headers 代码,并且不 echo,只悄悄写文件供分析。

经过以上处理后,ta 的确会一直访问,这让我很有成就感,抓到你了但你并不知道!

接下来的事就简单了,cat attackers.log,一支烟时间,成千上万个相同 IP,这是攻击者无疑,用毛笔隶书记下来,再加粗。

以上是找出一个攻击者 IP 斗智斗勇的全过程。然而……

.zip + .exe + .rar 有近 200 个,网站也有 7 个,要这样一个个找出来吗?

是,也不是。因为干掉一个 IP 就会减少很多攻击,基本上是 BAN 掉一个 IP 就将剩余攻击量减少 50%。

数据统计:七个站 200 个左右 exe/zip/rar 文件,共找出 11 个 攻击者。

然后,一如往常,风平浪静。

二、屏蔽 ta 们

CF 这么强大的平台,阻止 IP(s) 的功能肯定是有的。登录进去,不用太费力就能找到,直接给答案,在“Firewall -> Firewall Rules”下躺着。

但这个功能只能逐站 block IP(s),后来发现在“Firewall -> Tools -> IP Access Rules”模块下能为所有网站添加 IP 禁访规则,推荐使用!

如果没用 CF,Linux 的 iptables 命令也能搞定,但要注意有可能你的 Linode 在重启后会复位 iptables 设置,在 Linode 里作相关设置即可。

***********

至此,问题解决,以后类似问题依葫芦画瓢即可。

以上所有过程,难在找出第一个攻击者。

Post a comment