Cloudflare 2025年 倍に膨らんだ設定ファイルによる世界的な障害
攻撃ではない。データベースの権限を明示にする変更で、列の一覧を引く問い合わせが重複を返し、ボット判定の特徴のファイルが倍に膨らんだ。プロキシは特徴の数に上限を持ち、超えたファイルを誤りとして panic した。ファイルは5分ごとに作られ、数秒で全世界へ届いた。止める所は、自社で作った設定も外からの入力として確かめること、最後に正しかった版で動き続けること、設定もコードと同じく段階を踏んで配ることにある。
要点
- 11時05分、ClickHouse の利用者が下の表への権限を明示に持つよう変えた。列の一覧を引く問い合わせがデータベースの名前で絞っておらず、下の表の列も返すようになった[1]。
- その問い合わせで作るボット判定の特徴のファイルが倍に膨らんだ。プロキシは特徴の数の上限を200とし、使っていたのは約60だった。上限を超えたファイルで、新しいプロキシの FL2 が panic した[1]。
- ファイルは5分ごとに作られ、権限の変更が段階的に進んでいたため、正しいファイルと誤ったファイルが交互に配られた。落ちては戻る様子から、当初は大規模な DDoS を疑った[1]。
- 14時24分に新しいファイルの作成と配信を止め、正しかった版を配り直して中心のプロキシを再起動した[1]。
- CrowdStrike の2024年の件と同じく、数を前提にした読み手と、段階を踏まずに全部へ届く設定の組み合わせだった。違いは、落ちたのが利用者の空間のプロキシで、配り直しで戻せたことにある。
何が起きたか
| 時刻 UTC 2025年11月18日 | 出来事 |
|---|---|
| 11時05分 | データベースのアクセス制御の変更を展開する[1] |
| 11時20分頃 | 網が中心の通信を届けられなくなり始める[1] |
| 11時28分 | 変更が顧客の環境に届き、顧客の HTTP の通信で最初の誤りが出る、と年表は書く[1] |
| 11時31分から35分 | 最初の自動の試験が検知し、11時32分に人が調べ始め、11時35分に障害の会議を立てる[1] |
| 11時32分から13時05分 | Workers KV の誤りの増加を主な症状と見て、通信の操作やアカウントの制限を試す[1] |
| 13時05分 | Workers KV と Cloudflare Access を、前の版の中心のプロキシへ回す。影響が減る[1] |
| 13時37分 | ボット判定の設定ファイルが引き金と確信し、最後に正しかった版へ戻す作業に絞る[1] |
| 14時24分 | ボット判定の設定ファイルの作成と配信を止める。古い版で回復することを試して確かめる[1] |
| 14時30分 | 正しい設定ファイルを全世界に配り、主な影響が解ける[1] |
| 17時06分 | 崩れた状態の仕組みを全部再起動し、全部が戻る[1] |
| 2025年12月5日 | 別の設定の変更で、網の後ろの応用の28%が約25分間、通信を受けられなくなる[2] |
| 2025年12月19日 | 2つの件を受けた計画 Code Orange: Fail Small を出す[2] |
| 2026年4月7日 | 200人を超える技術者で、非常時の権限の道を使う訓練をする[3] |
| 2026年5月1日 | 計画の作業を終えたと書く[3] |
- 始まりの時刻は、本文の冒頭が11時20分、年表が11時28分と書く[1]。冒頭は網の失敗の始まり、年表は顧客の通信の最初の誤りを指している。
- Cloudflare は、2019年以来の最悪の障害で、6年余りの間に中心の通信の大半が止まった障害は無かったと書く[1]。影響を受けたサイトの数や損害の額は、公表に無い。
| 製品 | 影響 |
|---|---|
| 中心の CDN とセキュリティ | HTTP の 5xx を返す。FL2 では誤り、古い FL では誤りは出ずボットの点数が全部0になり、ボットを拒む規則を置いた顧客で誤検知が大量に出た[1] |
| Turnstile | 読み込めない[1] |
| Workers KV | 入口が中心のプロキシを通るため 5xx が大きく増える[1] |
| 管理画面 | ログインの画面に Turnstile があるため、多くの利用者がログインできない[1] |
| Access | 13時05分の切り戻しの開始まで、多くの利用者で認証が失敗する。失敗した利用者は誰も先の応用に届かず、既にある接続は影響が無い[1] |
起きた仕組み
| 段 | 何があったか |
|---|---|
| 権限 | ClickHouse の群れでは、分散の表を default というデータベースに置き、実の表を各断片の r0 というデータベースに置く。分散の問い合わせを共有の系のアカウントでなく最初の利用者のアカウントで走らせる作業の一部として、11時05分に、利用者が r0 の表への暗黙の権限を明示に持ち、その表の情報も見えるようにした[1]。 |
| 問い合わせ | 特徴のファイルを作る処理は、system.columns から表の列の一覧を引いていた。この問い合わせはデータベースの名前で絞っておらず、それまでは default の列だけが返ると前提していた。変更の後は r0 の列も返り、応答の行は倍を超えた[1]。 |
| ファイル | 特徴のファイルは数分ごとに作り直して全網に配る。新しいボットに素早く応じるための作りである[1]。重複した行がそのまま特徴になり、それまで決まった大きさだったファイルの大きさが変わった[1]。 |
| 読み手 | プロキシの各部品は、メモリを無制限に使わないための上限と、速さのためにメモリを先に取る作りを持つ。ボット判定は実行時の特徴の数を200に限り、使っていたのは約60だった。上限を超えたファイルで FL2 の Rust のコードが誤りを処理せず、Result::unwrap を Err に対して呼んで panic した[1]。 |
| 広がり | Workers KV と Access は中心のプロキシに頼る。管理画面は Workers KV と、ログインの画面の Turnstile に頼る[1]。捕まらなかった誤りに診断の情報を足す仕組みが CPU を大量に使い、応答も遅くなった[1]。 |
誤ったファイルは、権限の変更が済んだ節で問い合わせが走った時だけ作られた。5分ごとに正しいファイルと誤ったファイルが入れ替わり、網全体が落ちては戻った。内部の誤りとしては珍しい振る舞いで、同じ頃に Cloudflare の外に置いた状況の頁も偶然落ちたため、攻撃を疑った[1]。全部の節が変更を終えると、落ちたまま安定した[1]。落ちては戻る症状は、外からの負荷だけでなく、周期で作られる入力の揺れでも起きる。
CrowdStrike の件と比べる
2024年7月の CrowdStrike の件 と、型が近い。どちらも、振る舞いを決めるデータを、コードより速い道で全部に配り、読み手が数の前提を破られて落ちた。
| 観点 | CrowdStrike 2024年 | Cloudflare 2025年 |
|---|---|---|
| 誤りの入り方 | 新しい規則が初めて21番目の欄に具体の条件を置いた。規則そのものが変わった | ファイルを作る処理は変わらず、その上流のデータベースの権限が変わった。作り手のコードの差分には何も出ない[1] |
| 前の確かめ | 配る前の確かめの仕組みは、定義に照らして規則を通した | 作ったファイルを読み手と同じ上限で確かめる段は、公表に書かれていない。Cloudflare は、自社で作る設定ファイルの取り込みを利用者の入力と同じに固めるとした[1] |
| 配り方 | 段階を踏まずに全部の端末へ | 数秒で全網へ。設定を即時に配る仕組みは、2つの件に共通する点だと Cloudflare は書く[2] |
| 読み手の失敗 | 配列の外を読んで OS ごと止まった | 上限を超えた誤りを unwrap して panic した[1] |
| 戻り | 取り下げは、止まった端末には届かない | 配り直しと再起動で、主な影響は約3時間で解けた[1] |
CrowdStrike の欄の事実は、CrowdStrike 2024年 のページの出典による。2つの件から言えるのは、設定とデータの配信がコードの配信より緩いと、コードの品質の守りが全部すり抜けられるということである。Cloudflare も、ソフトウェアは段階を踏んで配っていたが、設定にはその方法を当てていなかったと書く[2]。
どこで止められたか
| 止める所 | この件で | Cloudflare の手当て |
|---|---|---|
| 前提を問い合わせに書く | default の列だけが返るという前提が、問い合わせに書かれていなかった[1] | 2026年5月の規則集に、処理の前に上流の依存が期待した状態かを確かめる、という規則を入れた[3] |
| 作った物を読み手の規則で確かめる | 特徴の数が上限を超えたファイルが、そのまま配られた[1] | 自社で作る設定ファイルの取り込みを、利用者の入力と同じに固める[1] |
| 設定も段階を踏んで配る | 設定は数秒で網の90%の機械に届く仕組みで配っていた[2] | 設定の変更を包みにまとめ、健全さを見ながら段階的に配り、自動で戻す仕組みを作った。社内の設定の変更は、多くの場合、即時には届かなくなった[3] |
| 読めない版は捨て、前の版で動く | 読めないファイルで panic した[1] | 読めない設定を拒んで前の設定を使う。前の設定も無ければ通す側に倒す。Rust で .unwrap を試験と build.rs の外で使わない規則を入れ、AIによるコードの点検で守らせる[3] |
| 部品が落ちても通信を落とさない | ボット判定の部品の失敗が、中心のプロキシの通信を落とした[1] | 部品が落ちても、ほどほどの判定で通信を通すべきだったと書く[2]。不要な実行時の依存を外し、通信の群れごとに独立した写しを動かす分割を始めた[3] |
| 直す道を落ちる側に頼らせない | Turnstile が落ちて顧客が管理画面に入れず、社内でも守りの仕組みが道具への接続を妨げた[2] | 18の主な仕組みに予備の認可の道を作り、訓練をした[3]。機能を全体で止める旗を増やす[1] |
2と4のどちらかがあれば、膨らんだファイルは通信を止めなかった。3があれば、止まっても一部の段で気付けた。Cloudflare は、同じ変更が今出たなら、配信の早い段で見つかり、通信のわずかな割合にしか及ばないと書く[3]。
守り方
悪い例と直した例。架空の判定の部品が、配られた特徴のファイルを読む
// 悪い例 上限を超えたら誤りを返すが、呼ぶ側が unwrap する
let features = FeatureSet::parse(&bytes, MAX_FEATURES).unwrap();
// 直した例 読めない版は捨て、最後に正しかった版で動き続ける
match FeatureSet::parse(&bytes, MAX_FEATURES) {
Ok(fs) => self.current = Arc::new(fs),
Err(e) => {
metrics::counter!("feature_file_rejected").increment(1);
log::error!("feature file rejected: {e}"); // self.current は前の版のまま
}
}
悪い例と直した例。架空の列の一覧の問い合わせ
-- 悪い例 見える範囲の全部のデータベースから同じ名前の表の列が返る
SELECT name, type FROM system.columns
WHERE table = 'request_features' ORDER BY name;
-- 直した例 どのデータベースの表かを書く
SELECT name, type FROM system.columns
WHERE database = 'features' AND table = 'request_features' ORDER BY name;
- 作った後の確かめも置く。作り手は、行の数が前回からどれだけ変わったか、名前の重複が無いか、読み手の上限を超えないかを見て、外れたら配らずに知らせる。前回の倍になった特徴のファイルは、その時点で止められた。
- どちらへ倒すかは部品ごとに決める。ボット判定が使えない時に通信を通すのは判定の精度を一時的に落とすだけで済むが、認可の確かめで同じことをしてはいけない。失敗した時に開く作りの危うさは A10 例外的な状況への不適切な対応 にある。
- 機能を全体で止める旗を、配信の仕組みと別に持つ。この件では、ファイルの作成と配信を止めるまでに約3時間かかった[1]。
- 捕まらなかった誤りの報告やコアダンプが、資源を食い尽くさないよう上限を置く。この件では診断の仕組みが CPU を使い、応答を遅くした[1]。
- 管理画面のログインと、障害の時に使う社内の道具が、落ちる側の製品に頼っていないかを棚卸しする[2]。
- 落ちては戻る症状を見たら、外からの負荷と並べて、周期で作られる入力と、段階的に進めている変更を疑う。
- AIに書かせたコードでは、
unwrapや何でも受ける例外の処理のような、誤りを素通りさせる書き方を差分で探す。Cloudflare は同じ型を規則にし、AIの点検で差分を止める[3]。人の読み方は AIの出力を確かめる にある。
参照
- Cloudflare outage on November 18, 2025 Cloudflare、2025年11月18日
- Code Orange: Fail Small — our resilience plan following recent incidents Cloudflare、2025年12月19日
- Code Orange: Fail Small is complete. The result is a stronger Cloudflare network Cloudflare、2026年5月1日