Cloudflare 免费版遭遇爬虫洪流:是什么阻止了它,以及我们关闭了哪些功能

运维

一天早上,我们的一个商品详情页网站打不开了。Cloudflare 向访客显示 524 错误,源站每页加载需要两到六分钟,而大约十个小时内没有任何警报。原因是爬虫通过住宅代理以每秒约 225 次请求的速度进行抓取。

洪流的形态

每个请求都渲染页面,因此每个工作进程排队数百次渲染并达到 CPU 上限。

为什么按地址限制无济于事

速率限制统计每个地址的请求数。当数千个地址每个只发出一到三次请求时,没有任何单个地址接近限制。屏蔽国家会屏蔽我们的访客。爬虫难以廉价伪造的是像以前访问过该网站的浏览器那样行事。

在 Cloudflare 边缘:三条免费规则

免费版允许每个区域使用五条 WAF 自定义规则。我们使用了三条,全部采用托管质询而非直接屏蔽,因此被误判的人可以点击通过:

这三个规则都会放行 Cloudflare 验证过的机器人、自报为机器人的用户代理、我们自己的地址、API 和 webhook 路径,以及非页面文件。两天后,流量洪峰仍在持续:仅一小时内,伪浏览器规则就挑战了超过 10,000 个请求。Cloudflare 每次查询返回的 10,000 个事件来自 9,627 个地址,其中没有任何一个地址的请求数超过 4 个。

在源站:应用中的一道关卡

无头浏览器部分拥有完整的浏览器请求头,因此在紧急规则关闭时,仅靠边缘规则无法拦截它。我们在应用本身中,在页面渲染器前放置了一个小型中间件:

在第一分钟内,该关卡拒绝了约 6,700 个伪浏览器,并挡下了约 6,700 个陌生人,同时以每秒约 9 个页面的速度服务陌生人。慢速请求降至零,worker 的 CPU 从满载降至 12% 到 15%,内存从每个 4 到 5 GB 降至 0.65 GB。

我们保持关闭的功能

要点

通过住宅代理发起的流量洪峰很容易通过其缺失项来识别:浏览器 fetch 请求头、cookie 和 Referer。在边缘拦截它,将陌生人限制在 worker 能渲染的范围内,并确保服务器之外的某些东西能在页面停止打开时注意到。Night Watch 将这三者打包在一起:看门狗、带有紧急规则自动切换功能的规则,以及针对 Python Web 应用的关卡。

已更新: