Cloudflare 经历了大规模中断,导致世界各地的服务暂时返回 5xx 错误。
直接原因是由于ClickHouse的权限变更,Bot Management的配置文件变得太大,导致代理无法处理。
内容
故障开始时间和网络状态
该问题于世界标准时间 11:20 出现,与日本夜间时间一致。紧接着,5xx在全球范围内迅速崛起,呈现出异常迅猛的上涨势头。
在此之前,错误率是稳定的,直到不久前才观察到异常的增加或减少。处理突然开始堵塞,我们强烈怀疑基础设施方面的内部原因。
一时间,误差不断循环上升和下降。这是因为配置文件作为正常版本和异常版本交替分发,并且各个边缘的状态不一致。
同时,响应延迟也增加,并且比以前更重的日志处理的影响仍然存在。这种结构增加了内部负载并导致许多请求(包括身份验证)累积。
早期的 5xx 在 11:28 出现,并在 14:30 倒带时平静下来。不过,影响完全消失有一个时间差,而且这种天气持续了很长一段时间,直到下午5点左右。
错误识别的攻击嫌疑以及识别原因的过程
故障一开始,Workers KV 中的错误很突出,看来数据采集的延迟涉及到另一个函数。在这个阶段,外部攻击的可能性成为候选,广域监视得到加强。
甚至连状态页面都出现暂时无法加载的情况,这似乎是大规模 DDoS 的迹象。然而,越来越明显的是,区域偏差和日志特征与攻击模式不匹配。
随着调查的进展,值得注意的是,错误同时发生在新旧代理上。而不是外部因素根本原因是公共设置文件中存在错误。这就是流量。
有时错误率会在某些时候下降,有证据表明会自动回滚到旧配置。此行为显示了配置文件各代之间的差异。
异常配置文件的分发引起了连锁反应。确定了这一点后,调查的重点是 Bot Management 生成的特征文件。
日本时区及对国内用户的影响
在日本,夜间高峰期恰逢从商业到一般用途等各种服务的一系列身份验证失败。我们已经确认,在很多情况下,Turnstile 挑战不会显示,并且您无法登录。
国内的服务往往会在同一个平台上进行CDN、WAF、认证辅助等多层配置,甚至一次配置失败很容易影响大范围,这次就是一个典型的例子。
也有一些网站即使在同一时间段也没有出现问题。使用单独 CDN 或将身份验证置于基础架构外部的方法的配置不会引用此配置文件,因此影响有限。
这种差异显然是由哪些功能依赖于哪些层决定的。影响力蔓延的原因多个重要功能依赖于单一设置的结构它位于
国内企业无法准确了解其依赖人群的问题这提供了一个例子,说明残疾的表象与现实有多么不同。
Cloudflare 机器人管理和 ClickHouse 更改的问题
特征文件变大的过程
特征文件是用于Bot判断的特征列表,每隔几分钟自动生成一次。本来就是几百行规模的稳定格式,代理加载也落在一定范围内。
当故障发生时,该文件膨胀到正常大小的两倍以上,并且行数继续快速增加。这是内部查询获取意外列信息导致输出内容过多的结果。
臃肿功能的持续分布超出了旧代理和新 FL2 的加载限制。因此停止应用配置文件本身的行为它导致
行数的突然增加并不是暂时的负载,而是在生成过程中出现结构崩溃的特征。根据到达的边缘,行为会有所不同,并且不稳定的情况会蔓延到所有层。
由于该文件被用作确定多个函数的基础,因此在交替接收正常和异常信号的情况下,行为往往会波动,并且问题仍然是每个边缘的状态不一致。
为什么由于 system.columns 规范更改而发生重复
由于 ClickHouse 权限系统的更改,从 system.columns 表中检索的列信息现在包含重复项。生成过程基于对列进行唯一处理的假设,因此不支持此更改。
在按原样处理重复列的设计中,行将在特征提取阶段重复。结果,生成了比平常更大的功能列表,从而导致配置文件更大。
配置生成逻辑基于上限进行操作,但这次假设被打破了。在没有空间控制的情况下,到达新旧代理的行数增加,导致不可读。
重复的列信息直接导致特征文件变得臃肿。这是这次的重点。无法保持内部处理的一致性,导致直接命中读限制检查。
虽然规范变更本身是有计划的,但可以说,这是由于依赖的内部逻辑没有跟上而形成结构性差异的情况。
正常文件和异常文件如何交替分发
生成过程在多个节点上独立运行,每个节点按照自己的时间输出文件。这种机制是正常版本和异常版本并存的背后原因。
一些节点返回具有重复列的查询结果,而其他节点则获取传统的列结构。这种差异变成了输出的差异,并且创建了两种类型的配置文件的情况继续存在。
分发是逐边进行的,因此不同时间到达的文件并不统一。不同的版本切换很快,导致各个边缘的状态发生波动。
由于异常版本和正常版本交替到达而导致行为不稳定的结构这就导致了5xx周期性增加和减少的结果。
最终,我们停止了生成过程,转而采用永久分发过去正常版本的策略。随着这一切换,周期性波动逐渐收敛。
Cloudflare FL2 新代理错误以及 5xx 的原因
超过预分配限制导致的错误行为
在代理内部,预先确定最大特征数,并且该机制使得在执行期间不会确保不必要的空间。这是保持处理稳定性和速度的先决条件。
当收到异常特征文件时,特征数量超过了这个最大数量,并且在加载阶段超出了限制。在通常无法达到的条件下,它会停止运行以提供保护。
加载阶段超过上限即停止处理这是性能优化的残余,可以说是没有考虑到异常值的设计造成的。旨在减少负载的系统实际上导致了停电。
由于配置文件在整个网络中快速部署,因此多个点同时达到限制,而不仅仅是几个边缘发生中断。这会导致大范围的停电。
除非进行更正,否则这种情况不会自动解决。如果持续下发异常版本,系统会在各个地点反复停止。
解开 Rust 代码引起的恐慌
在FL2中,很多流程都是用Rust编写的,内部使用unwrap来评估读取结果。这是预计不会返回错误的部分。
实际上,超出了读取限制,返回了错误,并且解包失败,导致了恐慌。这是 Rust 的标准保护机制,不容忍异常值。
当意外的返回值被传递给 unwrap 时会发生恐慌的结构。现在已经浮出水面。这是表现为停止的安全机制的示例。
Rust遵循内部类型和约束,因此它不会忽略异常返回值并继续处理。必须始终明确处理异常值。
恐慌之后,代理重新启动,5xx 继续运行,直到稳定下来。如果异常版本被重新分发,同样的行为将会再次重复。
FL 和 FL2 效果不同的原因
传统的 FL 有自己的实现,并且对特征处理有更宽松的限制。即使功能文件变大,处理也可以在禁用机器人检测的情况下继续。
在FL2中,为每个函数设置了详细的限制,并组织了内部处理的类型和结构。不允许超过上限等异常值,优先停止。
所以FL通过只是因为机器人判断被破坏,但FL2有一个停止的结构。它变成了。即使是同一个文件,效果也大不相同。
由于这两项服务同时运行,因此影响范围各不相同,一些服务频繁出现 5xx 错误,而另一些服务仅出现机器人功能误报增加的情况。
代理生成的差异直接影响了差异,而这就是造成这种行为混乱的流程。
Cloudflare Workers KV 和 Access 等下游服务出现故障
Workers KV 返回的错误率较高
Workers KV 的结构是通过代理处理读取请求,因此如果上游变得不稳定,错误将直接反弹回来。发生故障时,代理反复停止并重新启动。
导致KV前门返回大量5xx,缓存引用和配置读取暂时不可用。这是无法使用正常容错的情况。
上游代理挂掉直接导致KV错误率高的结构下游没有独立绕行。依赖顺序与操作直接相关。
影响期间,对后端的请求增加,负载逐渐增加。此行为与其他功能相关,导致整体响应速度降低。
最终KV侧应用了专用bypass,流程切换到不经过代理的路由。结果,反应稳定了。
接入认证失败及现有会话的处理
访问认证是向代理发送登录请求,验证通过后即可使用的结构。如果代理停止,登录请求本身将无法完成。
在中断期间,许多新的身份验证尝试失败,许多用户无法继续访问登录页面。然而,已经发布的会议继续保留。
新会话失败但现有会话保持的两层状态这会根据用户的不同产生不同的结果。这是一个按原样公开身份验证基础设施结构的示例。
大多数设置更改都没有反映,并且更新需要很长时间。内部认证数据也依赖于代理,如果同步过程停止,就会暂时变得不一致。
切换代理路由后,这种情况逐渐解决,恢复到稳定的认证流程。
对十字转门和仪表板的级联效果
Turnstile 是一种用于登录页面等的验证功能,它也可以通过代理运行。当发生故障时,页面无法加载并且页面无法继续。
导致仪表板登录成功率大幅下降。除非 Turnstile 响应,否则无法到达登录过程,并且该过程停止在预身份验证阶段。
验证功能不起作用,无法登录。这造成了用户难以了解情况的问题。这是因为它在屏幕上看起来像是一个简单的加载失败。
下半年,重试请求集中,导致仪表板负载超出正常处理能力。这种额外的负载进一步加剧了响应延迟。
最终,在验证过程稳定后,集中负载得到解决,管理屏的运行也恢复到正常状态。
Cloudflare防复发措施及企业应采取的要点
对内部生成的文件进行严格的验证和终止开关
此问题是由内部处理创建的配置文件引起的,导致整体行为变得不稳定。这是缺乏对内部产品而不是外部输入的验证的表现。
作为对策,重要的是在生成阶段检查结构并验证含量的上限。这个过程需要一种在检测到异常值时停止部署的机制。
终止开关允许您立即禁用生成的设置可以被视为阻止广泛传播的一个因素。内部分配的速度越快,这种机制就越重要。
公司还可以检查其公司的设置反映过程是否是单向的。有办法撤销不正确的设置与发生故障时的稳定性直接相关。
内部生成过程越复杂,设计过程中需要的验证点就越多。需要一个流程来显式处理异常值而不吸收它们。
旨在确保错误报告和监控机制不会占用资源
发生故障时,收集错误信息的观察机制就会启动,但这一次这是增加CPU负载的一个因素。这种结构随着错误数量的增加而增加负载。
观察是必要的,但只有在出现异常时才变得沉重的系统是不健康的。需要进行轻量级监控和处理以减少重复报告。
发生故障时监控本身不会夺走处理能力的结构很重要,也会影响整体恢复速度。它旨在抑制正常和异常情况下的负载差异。
公司可以检查是否过多地增加了测量目标的数量或记录了过多的状态变化。需要一种信息收集不会干扰服务操作的结构。
希望将监控机制调整为“可靠地采取最小必要量”并减少异常情况下的负载。
日本企业可以在自己的运营设计中审视的要点
在依赖外部服务的结构中,更改某些设置将影响整个系统。此故障可以视为依赖层次结构越深,影响越大的示例。
首先要记住的是为单点故障做好准备,并了解如果外部身份验证或 CDN 出现故障,您自己的服务将会受到多大影响。
双轨认证路由及设置反射增加故障期间的恢复能力。外部依赖越多,准备多条路由就变得越重要。
另一点要检查的是您的公司是否可以控制倒带或暂停设置。允许响应外部停止而切换某些功能的机制是有用的。
通过预测故障的影响范围并可视化每个依赖层的“如果故障停止会发生什么”,您可以提高整个操作设计的稳定性。
关于我
