こんにちは!
クラウドフレアから、この前のインシデントの解説が出たのでまとめようと思います!
原因
概要
障害の直接的な原因は、Cloudflareの「Bot Management機能」で使用されるfeature file(機能構成ファイル)を生成する過程に不具合が生じ、当該ファイルが想定より大幅に肥大化し、ネットワーク上の複数プロキシ/モジュールに影響を及ぼしたことです。
詳細な流れ
- Cloudflareでは、クリックハウス(ClickHouse)データベースのクエリが、「http_requests_features」などのテーブルからname, typeを取得する処理を行っており、これがBot Managementのfeature file生成ロジックとして用いられていました
- そのクエリにおいて、データベース権限の変更が段階的に展開されたことで、「default」データベースだけを対象と想定していたところ、別データベース(r0)由来の重複列が返されるようになりました。つまり、クエリ結果に予期せぬ重複が出現
- その結果、feature file生成ロジックが重複を含んだ多数の “feature(特徴量)” 行を含むファイルを出力。このファイルサイズ/行数ともに想定を大幅に超え、Bot Managementモジュールが “約200” という上限数を超える “約60→超過” といった状況で動作を継続
- 生成されたファイルは、世界中のCloudflareネットワークマシンへ配布され、プロキシ/ルーティングモジュールがこのファイルを読み込んでいたため、複数マシンでプロキシ処理が失敗する状態に陥りました
- 初期にはCloudflare側も「ハイパースケールなDDoS攻撃かもしれない」という仮説を持っていましたが、実際には設定とプロセスの内部不具合であることを特定しました
なぜこのような結果になったか
- ファイル生成/配布の仕組みにおいて、ファイルサイズ/行数の上限を越えた場合のフォールトトレランス(障害耐性)が十分設計されていなかった
- 重複取得を招くクエリ設計において、データベーススキーマ/ユーザー権限変更による影響を十分考慮していなかった
- ネットワーク全体に配布された設定ファイルが引き金となったため、影響範囲がグローバル規模となった
- 初動時点で仮説(DDoS)に時間がかかり、原因の特定・修正開始までタイムラグがあった
解決対応(インシデント中/復旧フェーズ)
Cloudflare公式ブログによると以下のような手順で対応が行われました。
- 14:24 UTC に、自動生成および配布中の不正な feature file の生成および配布を停止しました
- 既知正常なバージョンの feature file を手動で挿入し、配布キューに投入
- コアプロキシ(traffic processing core proxy)を再起動して、各モジュールが正常な設定で読み込み直されるようにしました
- 14:30 UTCごろには「コアトラフィックの大部分は正常化」し、17:06 UTCには全システムが復旧したと公式発表しています
- 復旧後、増加したトラフィックが一斉に流れたことによる副次的な負荷増にも対処。各種サービス/モジュールの再起動・ロードバランス調整を実施
今後の防止策(Cloudflareの公表分)
Cloudflareはこの障害を重く受け止め、再発防止に向けた改善策を公表しています。
- ファイル生成/取り込みパイプラインの「堅牢化(hardening)」。たとえば、生成ファイルの行数・サイズが異常になった際のフォールトトリガーやアラートを強化
- 機能のグローバルキルスイッチ(feature kill-switch)を設け、異常時にモジュールを速やかに停止できるように
- コアプロキシ/モジュールが「コアダンプ」や大きな設定変更により過剰負荷を受けないよう、エラーモード(failure modes)の見直しを進める
- 設定変更時の影響範囲(データベース権限変更)をより慎重に管理。クエリ設計・スキーマ設計における防御設計を強化
- 配布された設定ファイルがキャッシュ/一斉配布される過程でトラブルを引き起こさないよう、配布プロセスの段階的ロールアウト・モニタリングを改善