一夜之间天塌了

2025年1月14日20:44,我收到了一封来自Vercel的自动邮件,内容让所有博客创作者都心花怒放——Your site is growing! 你的站点正在蓬勃发展!……已经使用了75%的用量

自从博客加入V2EX的VXNA计划后,浏览的人数不断增长,以往根本用不完的每月2000次访问追踪(Site Analystics)额度,几乎每个月都能早早收到用光100%的提醒,我也为自己感到高兴。

我当时并没有多想,继续干其他的事情去了。

然而第二天早上起床的时候,我又收到了一封凌晨00:44发来的邮件,写的是我100%的额度已用完。我当时很纳闷,我最近也没发什么特别吸引人眼球的东西啊,怎么这25%的额度用得如此之快。

仔细一看,我用光的并不是访问追踪的额度,而是一个叫做快速数据传输(Fast Data Transfer)的东西。仔细研读了文档后得知,只要网站和用户设备之间发生数据传输,就会使用到这个传输用量,免费计划总共100GB。这个用量并不会像访问追踪一样,每个月更新,用光了就没了,必须升级套餐。

photo_2025-01-15_09-10-50.jpg

看着1月14日那一个耀眼的柱子,我不仅感觉有点错愕。我浑浑噩噩地合上笔记本,然后出门上课去了,那一整天我心神不宁。

中午吃饭的时候,我将信将疑地更新了一下主页,在最上方加了一个门头——本站正在受到攻击…… 推送是正常的。我当时甚至还抱着侥幸心理,会不会其实这不影响我推送,也不影响浏览,我放着它不管其实也不会有什么问题。

但是我错了,16号早上起床的时候再看博客就已经进不去了,显示暂时停用。

我这才接受现实,这个问题得想办法解决才行。

保卫战

1月17日早上,我把解除了原博客Github和域名的绑定,用一个新邮箱重新注册了Vercel账号,重新部署上线。在V站水友的建议下,Vercel可以用来管理博客更新,CloudFlare用来部署服务器,专业的事情交给专业的做。CloudFlare的防火墙应该能够为我挡下一些奇怪的访问。我把能开的东西都打开了, 比如什么机器人防护,反正感觉不影响正常流量访问的开关都开了。

但事情还是出乎了我的意料。

1月17日中午,当我点开CloudFlare的流量追踪时,几个耀眼的spike再次映入眼帘,提醒我快速传输数据用完一半的邮件也接踵而至。我心里暗自咒骂起来,没完没了了这是,md甚至还没坚持过一个早上。

数据传输用量的数字如同老式水表的飞轮,飞速转动着,每次刷新都能看见用掉了1GB左右的数据。我赶紧打开了Vercel上的Attack Challenge Mode,数字跳动的速度才减缓了下来。

Pasted image 20250126103730.png

但是这也不是办法啊,我不可能每次用完都狡兔三窟,迁移博客虽然简单,但我也没那么多邮箱号可以挥霍啊!

我找到了CloudFlare的WAF(Web Application Firewall)页面,把我遭遇到情况一五一十地向ChatGPT讲述,请它帮我想规则。

首先,我们注意到几个spike,分别来自5个不同的ip,每个ip都请求了约500次,然后就停止访问了,这种非常不正常的访问模式绝对不可能来自正常用户,直接拉黑IP。

其次,我遭受到的很可能是爬虫攻击,大部分爬的是我的feed.xml,一般的rss阅读器不可能在短时间内反复爬取这么多次,所以需要一个Rate Limiting Rule,如果单位时间内重复发送了太多次请求,那就弹JS验证。

还有小部分访问的是一些奇怪的目录,比如.php,.txt等等文件,在我的博客里根本不存在这些文件。这些据Chat老师描述,应该叫做嗅探(sniff),爬虫工具尝试在我的博客里面寻找一些重要文件,如果正好撞到有这个文件,或许能抓到密钥或者其他的敏感信息。正常访问博客的人也不会点到这些目录去,如果有尝试嗅探特定后缀的访问,直接block掉,没有一个是无辜的。

基本这几条规则下去,大部分攻击就已经被挡住了。

其实整个过程远远没有我描述地这么轻松,我还是走了不少弯路的,很多东西都是一点点试出来的。

一开始我把几个近期数次访问我xml的ip全拉黑了,后来发现Inoreader停止抓取我的RSS订阅,我才意识到RSS阅读器的本质就是定期抓取我xml的内容变更,一昧地全部封杀,其他人可能就收不到我的更新通知了。甚至几个一口气访问几次的IP封掉后我才发现是我自己。我这才开始思考,怎么去区分正常的访问和恶意的抓取。

在Chat老师的指引下,我也写过一些没有用的规则,比如一开始的几个访问量巨大的IP显示都来自美国,我也加了一条禁止美国用户访问的规则。管用了几分钟之后,另一个来自中国的IP便开始疯狂地请求。

所以,写规则的关键还是在于精细化地管理,如何才能准确地只命中恶意访问,而不中伤正常用户,这是个学问。

在把服务器部署到CloudFlare上面之后,我有一段时间自己都无法打开自己的博客了,提示too many redirects。在谷歌上一搜才发现,这是一个很普遍的情况,解决办法就是在SSL/TLS-Overview-Configure,把Flexible改成Full或者Full(Strict)即可。

但是打开之后,新访客访问我的博客都需要做一次浏览器检查,等待1-2秒之后才能正常访问,只要证书没过期,下次访问就不需要再检查浏览器了。这个确实对用户体验算是一个不小的打击,但是我暂时没有想到其他的解决办法,暂时先这么留着吧。至少先保证来者都是正常访客,活下来更重要!

为什么是我?

看到后台数据回归正常之后,我不禁想问,为什么是我?

我想了几个可能性——

第一,现在AI炼丹时代,只要是被搜索引擎收录的网址都难逃被拿去喂AI的命运,被爬是非常正常的一件事情。在发布捷克留学长期签证DIY这篇博客之后,我发现谷歌搜索「捷克」「长期签证」,我的博客长期以来一直出现在结果前三。

第二,黑暗森林,要想自己的博客不被发现,那就不要发声,不要暴露,不要宣传。少了平台保护的普通小站点,防护只能靠自己。只要暴露了,迟早有一天恶意访问会找上门的。

在事发的前几天,我把自己的博客放到了一个收录了中国独立博客的Github项目上,当时合并完分支自己还觉得很自豪,我也是这个项目的贡献者之一了。但是后来想想,如果别人要找些网站来攻击,这个项目的列表将是一个绝妙的素材。这个项目上的很多博客都已经死掉了,会不会也是因为这个呢?

第三,心理变态,就是看我博客不爽,直接攻击我博客最薄弱的地方——没有防护的feed.xml,对吧,159.xx.xxx.10?被Block了还发了几十万请求,也不知道检查一下,你不知道你这种爬法会给别人造成了多大困扰!??

Pasted image 20250126103341.png

这次事件后,真的让我对网络安全有了全新的认识,也让我的计算机技术知识增长了不少。在空闲的时间我会再去学习一些知识,防患于未然,让这个博客尽量安安稳稳地完成10年之约。

希望我的经历对你也有帮助,共勉!