Cloudflare 2025年11月18日服务中断事件
2025年11月18日UTC时间11:20,Cloudflare网络开始出现核心网络流量交付严重故障。互联网用户访问我们客户网站时看到错误页面,表明Cloudflare网络内部出现故障。
故障原因分析
此次问题并非由网络攻击或任何恶意活动直接或间接引起,而是由我们某个数据库系统权限变更触发。该变更导致数据库向机器人管理系统使用的"特征文件"输出多个重复条目,使该特征文件大小翻倍。这个超出预期的特征文件随后传播到构成我们网络的所有机器。
在这些机器上运行以路由流量的软件会读取此特征文件,使我们的机器人管理系统能够跟上不断变化的威胁。该软件对特征文件大小设置了限制,该限制低于翻倍后的大小,导致软件故障。
故障时间线
11:05 - 数据库访问控制变更部署 11:28 - 影响开始,部署到达客户环境,首次在客户HTTP流量中观察到错误 11:32-13:05 - 团队调查Workers KV服务流量激增和错误 13:05 - 实施Workers KV和Cloudflare Access绕过 - 影响减少 13:37 - 重点回滚机器人管理配置文件到最后已知良好版本 14:24 - 停止创建和传播新的机器人管理配置文件 14:30 - 主要影响解决,下游受影响服务开始观察到错误减少 17:06 - 所有服务解决,影响结束
技术细节
请求处理流程故障
每个到Cloudflare的请求都经过明确定义的路径:首先在我们的HTTP和TLS层终止,然后流入我们的核心代理系统(我们称之为FL),最后通过Pingora执行缓存查找或在需要时从源站获取数据。
在核心代理传输请求时,我们运行网络中可用的各种安全和性能产品。代理应用每个客户的独特配置和设置,从强制执行WAF规则和DDoS保护到将流量路由到开发平台和R2。
其中一个模块——机器人管理——是今天中断的根源。
ClickHouse查询行为变更
生成特征文件的底层查询行为变更导致文件包含大量重复"特征"行。这改变了先前固定大小的特征配置文件的大小,导致机器人模块触发错误。
具体来说,我们更改了ClickHouse集群的权限管理,使用户能够看到r0数据库中基础表的元数据。这导致以下查询开始返回"重复"列:
|
|
该查询没有按数据库名称过滤。随着我们逐步向给定ClickHouse集群的用户推出显式授权,上述查询开始返回列"重复项",因为这些列用于存储在r0数据库中的基础表。
内存预分配问题
在我们的代理服务上运行的每个模块都有许多限制,以避免无限制的内存消耗,并预先分配内存作为性能优化。在这种特定情况下,机器人管理系统对运行时可以使用的机器学习特征数量设置了限制。目前该限制设置为200,远高于我们当前使用的约60个特征。
当包含200多个特征的错误文件传播到我们的服务器时,达到了此限制——导致系统恐慌。触发恐慌的FL2 Rust代码如下:
|
|
受影响的服务
- 核心CDN和安全服务:HTTP 5xx状态码
- Turnstile:无法加载
- Workers KV:HTTP 5xx错误显著增加
- Dashboard:由于登录页面Turnstile不可用,大多数用户无法登录
- Email Security:临时失去对IP信誉源的访问
- Access:大多数用户身份验证失败
修复和后续步骤
现在我们的系统已恢复在线并正常运行,我们已经开始研究如何加强它们以防止未来发生类似故障。特别是我们正在:
- 以与用户生成输入相同的方式加强Cloudflare生成的配置文件的摄取
- 为功能启用更多全局终止开关
- 消除核心转储或其他错误报告淹没系统资源的可能性
- 审查所有核心代理模块的错误条件的故障模式
影响统计
故障期间,我们观察到来自Cloudflare网络的5xx错误HTTP状态码数量激增。正常情况下这应该非常低,直到中断开始前确实如此。
图表显示了我们系统由于加载不正确特征文件而失败的波动。值得注意的是,我们的系统会随后恢复一段时间。对于内部错误来说,这是非常不寻常的行为。
解释是文件由在ClickHouse数据库集群上运行的查询每五分钟生成一次,该集群正在逐步更新以改进权限管理。只有在已更新部分的集群上运行查询时才会生成错误数据。因此,每五分钟就有机会生成一组好或坏的配置文件,并迅速传播到整个网络。