速览Cloudflare 11.18 网络事故:一次权限变更如何引发系统雪崩

1 阅读3分钟

原文: blog.cloudflare.com/18-november…

基于这篇Cloudflare的事故复盘报告,概括如下:

1. 事件定性:非安全攻击,而是变更引发的系统崩溃

  • 性质: 这是一次严重的全球性故障(Cloudflare自2019年以来最严重的一次),导致核心网络流量中断。
  • 误判: 初期因症状类似(流量波动、状态页恰好不可用),团队误认为是超大规模DDoS攻击,但最终确认为内部系统问题。

2. 核心根因:蝴蝶效应(权限变更 -> 数据重复 -> 内存溢出)

故障链条非常清晰,展示了微小变更如何导致系统级雪崩:

  1. 起因(数据库层): 运维团队对ClickHouse集群进行权限变更,本意是允许用户显式查看底层表元数据。
  2. 触发(数据层): 一个用于生成“Bot管理特征文件”的SQL查询逻辑存在缺陷(未过滤数据库名)。权限变更后,该查询返回了重复的列数据(包含default库和底层的r0库),导致生成的配置文件内容体积翻倍
  3. 崩溃(代码层): 核心代理服务(FL2,Rust编写)读取该配置文件时,由于为了性能优化预设了内存分配上限(限制200个特征,而坏文件超过了此限制),导致代码触发Panic(崩溃),抛出 HTTP 5xx 错误。

3. 故障排查难点:间歇性“震荡”掩盖了真相

  • 现象: 故障并非一直持续,而是呈现“时好时坏”的震荡状态。
  • 原因: 数据库集群是分批更新的。只有查询命中已更新权限的节点时,才会生成坏文件;命中未更新节点则生成好文件。
  • 后果: 这种不确定性极大地干扰了故障定位,让团队误以为是攻击流量导致的系统不稳。

4. 级联影响范围

  • 核心受损: 核心CDN服务、安全服务直接返回5xx错误。
  • 下游受损: 依赖核心代理服务的内部组件(如 Workers KV、Access、Turnstile、Dashboard)随之崩溃或无法登录。

5. 改进措施与教训

Cloudflare提出的整改方向主要集中在防御性编程容错机制上:

  • 信任边界: 将内部生成的配置文件视为“不可信的用户输入”,加强校验和硬化处理(不能假设内部生成的文件永远正确)。
  • 熔断机制: 增加全局性的功能开关(Kill Switches)。
  • 资源保护: 优化错误处理逻辑,防止Core dump或错误报告本身消耗过多资源导致系统死锁(故障期间调试系统的高CPU占用加剧了延迟)。

一句话总结: 一次旨在优化数据库权限的常规变更,因SQL查询逻辑不严谨,导致生成的配置文件体积超出代码硬编码的内存限制,进而引发全球核心代理服务崩溃。教训在于:内部配置的输入处理应与外部输入同等严谨,且系统需具备更强的容错与降级能力。