墨筝

2025 年 11 月 18 号 cloudflare 崩溃复盘

2025-11-23

前言

全球领先的网络基础设施服务提供商 Cloudflare 于 2025 年 11 月 18 日(UTC 时间)发生了一次持续数小时的重大服务中断,导致全球大量网站和在线服务出现访问故障,包括 X(原 Twitter)、ChatGPT、Spotify、Roblox、Grindr、Canva 等热门平台均受到波及。尝试访问其服务网站的用户会看到一个错误页面,提示 Cloudflare 网络异常:

根据 Cloudflare 官方披露的故障全过程,引发该事故的核心原因并非外部 DDos 攻击或者恶意行为,而是内部一次常规数据库权限调整引发的连锁反应。故障详情与过程整理如下:

故障描述

根据 Cloudflare 官方披露博客以及多家监测机构的数据,中断于 UTC 时间 11:20(北京时间 19:20 左右)开始显现,用户大量报告出现 HTTP 500/5xx 错误、页面加载失败或“内部服务器错误”。高峰期,Downdetector 等故障监测网站本身也因依赖 Cloudflare 而短暂下线,进一步放大了混乱。

核心流量在 UTC 14:30 左右恢复正常,但控制面板(Dashboard)、API、Workers KV、Access 等应用服务直到 UTC 17:06 才完全恢复,整个事件持续约 5 小时 46 分钟。Cloudflare 表示,此次中断影响了其全球网络,未限定特定地区,但依赖其 Bot Management、Workers 或 CDN 的客户几乎全部受到不同程度冲击。

服务/产品 影响描述
核心 CDN 与安全服务 HTTP 5xx 状态代码,用户看到上述错误页
Turnstile(一个用户验证服务,通过更轻量、隐私友好的方式区分真实用户与自动化程序,如爬虫或恶意流量) Turnstile 无法加载
Workers KV(一种全球分布式、低延迟的键值存储服务,专为 Cloudflare Workers 设计,用于在 Cloudflare 的全球 300+ 节点的边缘网络中快速存储和读取数据) 由于核心代理出现故障,导致对 KV“前端”网关发出的请求失败,进而导致 Workers KV 返回的 HTTP 5xx 错误数量显著增加。
dashboard(用户管理 cloudflare 服务的控制面板页面) 虽然 dashboard 基本维持正常运行,但由于登录页面中的 Turnstile 不可用,导致大多数用户无法登录。
Access(cloudflare 的门禁服务) 从事故开始直到 13:05 启动回滚操作期间,绝大多数用户的身份验证都出现了失败。但在故障发生前已经建立的 Access 会话(Session)并不受影响。

故障根因

此次故障的根本原因来自于 cloudflare 的机器人管理模块,该模块中存在一个机器学习模型,用于给流经 cloudflare 的请求生成机器人评分以控制该请求是否可以正常访问服务。模型接收一个特征(机器学习模型用于预测请求是否为自动化请求的单个特征)配置文件(特征的集合)作为输入,特征配置文件每隔几分钟就会自动更新部署到 cloudflare 的整个网络中以便快速应对各种攻击手段。由于底层 ClickHouse 查询行为变更(详见下文),在生成特征文件时出现大量重复的数据,导致特征配置文件超出原有的指定上限,引发机器人管理模块出现异常。因此,对于所有依赖于机器人模块的流量,负责处理客户流量的核心代理系统都返回了 HTTP 5xx 错误代码。这也影响了同样依赖于核心代理的 Workers KV 和 Access 等服务。

特征文件大小超出

一个 ClickHouse 集群由许多分片(Shards)组成。为了从所有分片中查询数据,Cloudflare 在名为 default 的数据库中使用了所谓的“分布式表”(由 Distributed 引擎支持)。这个 Distributed 引擎实际上是去查询名为 r0 数据库中的底层表,这些底层表才是 ClickHouse 集群各分片上真正存储数据的地方。

以前,对分布式表的查询是通过一个共享的系统账户运行的。为了提高分布式查询的安全性和可靠性,查询后来改用初始用户(initial user)的账户来执行。

在故障发生之前,当 ClickHouse 用户查询系统表(如 system.tables 或 system.columns)以获取表元数据时,他们只能看到 default 数据库中的表。
切换查询账户之后,用户实际上已经隐式拥有了访问 r0 中底层表的权限,Cloudflare 团队在 11:05 做了一个变更,将这种访问权限显性化。这意味着用户现在也能看到底层表的元数据。这个操作主要是为了确保所有分布式子查询都能在初始用户下运行,从而更精细地评估查询限制和权限,避免某个用户的恶意子查询影响到其他人。

上述变更让所有用户都能准确获取他们有权访问的所有表的元数据。但不幸的是,过去的代码中存在一个假设,认为执行像下面这样的查询时,返回的列列表只会包含 default 数据库:

1
2
3
4
5
6
7
SELECT
name,
type
FROM system.columns
WHERE
table = 'http_requests_features'
order by name;

由于这个查询并没有过滤数据库名称。随着逐步向集群用户推出显性权限,在 11:05 的变更后,上述查询开始返回“重复”的列,因为结果中不仅包含了 default 数据库的列,还包含了存储在 r0 数据库中底层表的列。

机器人管理模块特征文件的生成逻辑刚好使用了这类查询来构建文件所需的每一个输入“特征(feature)”,查询响应现在包含了 r0 模式的所有元数据,实际上导致响应行数翻倍,于是最终输出的特征文件也直接翻倍膨胀了。

为什么特征文件超出会引发故障

Cloudflare 代理服务上运行的每个模块都设有一系列限制以避免无限制的内存消耗。具体到本次事件,机器人管理模块对运行时可使用的机器学习特征设定了 200 的数量上限。当那个翻倍膨胀后超出 200 个特征的问题文件分发到服务器时,系统发生如下 Panic(崩溃)报错,进而引发了 5xx 错误:

1
thread fl2_worker_thread panicked: called Result::unwrap() on an Err value

源于其 Rust 代码中的检查逻辑未能妥善处理这个错误,代码如下所示:

简单打个比方就是 cloudflare 的机器人管理模块就像一个大巴车,硬性规定最多只能乘坐 200 人,由于上一步的特征文件生成错误(数据重复),导致出现了超载,然后负责检票的代码(上述 rust 代码)发现人数超标之后并没有想办法容纳超出的人员,而是选择了原地崩溃,直接报警,于是处理请求的线程挂了,导致用户访问出现 5xx 服务错误。

后续处理与事件回顾

这是自 19 年以后 cloudflare 最严重的一次宕机事故,为了避免未来再次发生此类故障,cloudflare 给出的具体 action 包括:

  • 加固配置文件的摄入流程: 像对待用户输入的(不可信)数据一样,严格审查和处理 Cloudflare 内部生成的配置文件。
  • 启用更多功能的全局终止开关: 确保在紧急情况下能快速禁用特定功能。
  • 限制资源消耗: 消除核心转储(Core dumps)或其他错误报告耗尽系统资源的可能性。
  • 全面审查故障模式: 检查所有核心代理模块在遇到错误条件时的处理逻辑(避免直接崩溃)。

整个故障的时间线如下所示:

时间(UTC) 状态 描述
11:05 正常 数据库访问控制变更已部署。
11:28 问题开始显现 部署到达客户环境,首次在客户 HTTP 流量中发现错误。
11:32-13:05 Cloudflare 团队调查了 Workers KV 服务的流量激增和错误情况。 最初的迹象表现为 Workers KV 响应速度下降,进而导致下游的其他 Cloudflare 服务受到影响。尝试流量控制和账户限制等缓解措施,以便让 Workers KV 服务恢复到正常运行水平。首次自动化测试于 11:31 检测到问题,人工调查于 11:32 启动。事件呼叫于 11:35 创建。
13:05 实施了 Workers KV 和 Cloudflare Access 绕过措施 - 已减轻影响。 在调查过程中,针对 Workers KV 和 Cloudflare Access 使用了内部系统绕过措施,使二者回退到核心代理的先前版本。虽然代理的先前版本中也存在这个问题,但如下文所述,其影响较小。
13:37 工作重点是将机器人管理配置文件回滚至最近的已知合适版本。 确认机器人管理配置文件是此次事件的触发因素。团队通过多个工作流程研究了补救服务的方法,其中最快的方法是恢复该文件之前的版本。
14:24 已停止创建和传播新的机器人管理配置文件。 确定机器人管理模块是 500 错误的根源,而问题是由一个错误的配置文件引起,停止自动部署新的机器人管理配置文件。
14:24 新文件测试完成。 观察到使用旧版本的配置文件成功恢复,随后集中精力加快全球范围的修复进程。
14:30 主要问题已解决。下游受影响服务的错误开始减少。 在全球范围内部署正确的机器人管理配置文件,并且大多数服务已开始正常运行。
17:06 所有服务均已恢复。影响结束。 所有下游服务均已重新启动,所有操作完全恢复。

总结

cloudflare 的这次故障影响甚大,故障当日 Cloudflare 的股价下跌约 3%-4%,收盘价约 196 美元,较 11 月初历史高点 260 美元已回调超过 24%。分析人士指出,频繁的云基础设施中断(AWS、Azure、Cloudflare 在一个月内接连出事)正引发投资者对“单点故障风险”的担忧。

从技术角度出发,cloudflare 的这次故障核心还是在于机器人管理模块对异常输入的处理不够谨慎所致,当输入的特征配置文件大小异常时应该首先抛出告警,然后从缓存中取上一个正常版本的配置文件,而不是原地爆炸,直接抛出 panic。Cloudflare 处理着全球约五分之一的网页请求,这种处理逻辑还是有些过于粗暴了。

参考

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章