- 2023年8月28日、英国の航空交通管制運営会社 NATS の FPRSA-R 障害により2,000便以上が欠航し、費用は1億ポンド以上と見積もられた
- 混乱を引き起こした飛行計画は Eurocontrol IFPS が受理した 有効な計画 であり、NATS のシステムは ADEXP データと ICAO4444 経路を照合して英国空域区間を抽出しようとしていた
- 直接の原因は、地理的に異なる2つのウェイポイントが同じ識別子を持っていたことで、FPRSA-R は誤った 重複識別子 を離脱地点として対応付け、有効な英国区間を作成できなかった
- 主系統とバックアップ系統は同じロジックで同じ飛行計画を処理し、それぞれ critical exception を発生させ、20秒以内に maintenance mode に入り自動処理が停止した
- 航空機は引き続き安全に管制されていたが、単一の飛行計画が自動処理システム全体を停止させたフェイルモード、テスト不足、低レベルログに依存した復旧手順が問題として残った
2023年8月28日の NATS 障害の規模
- 英国の航空交通管制運営会社 NATS は、2023年8月28日に重大な技術障害を経験した
- BBC によれば2,000便以上が欠航し、費用は1億ポンド以上と見積もられた
- 障害は数十万人に影響した可能性がある
- 初期の報道では「誤った飛行計画」や「フランスの航空会社のミス」の可能性が取り上げられたが、問題を起こした飛行計画は Eurocontrol IFPS が受理した ICAO4444 準拠の飛行計画だった
- その後、障害を引き起こした実際の便は French Bee FBU731 と特定され、LAX/KLAX から ORY/LFPO に向かう便だった
飛行計画が NATS に到達する流れ
- 航空会社は飛行計画を Eurocontrol の IFPS に提出する
- IFPS が飛行計画を受理すると、出発空港の管制承認後に航空機は離陸できる
- この段階で NATS の入力は不要である
- IFPS は関係する航空航法サービス提供者に飛行計画を送信する
- NATS は航空機が英国空域に進入する少なくとも4時間前までに飛行計画を受け取る必要がある
- この4時間は処理上の問題を解決するためのバッファ時間として機能する
- Swanwick Centre の NATS En-route 運用では、データを FPRSA-R に渡す
- FPRSA-R は IFPS から受け取った ADEXP 形式データを、UK National Airspace System、すなわち NAS と互換性のある形式に変換する
- NAS は関連空域と経路情報を含む飛行データ処理システムである
ICAO4444 と ADEXP の違い
- ICAO4444 の飛行計画は、機械可読であり、必要に応じて人間も読める形式である
- 経路部分には速度、高度、ウェイポイント、経路名、
DCT のような直行飛行表示が含まれる
- たとえば
N0440 は 440 ノット、F310 は Flight Level 310 を意味する
- IFPS は ICAO4444 の飛行計画を ADEXP 形式に変換して送信する
- ADEXP には元の ICAO4444 飛行計画に加え、欧州地域の経路に関する追加の地理ウェイポイントが含まれる
- 英国に着陸せず英国空域を通過する便には、英国通過後の旅程に必要なウェイポイントも含まれることがある
- ADEXP の
RTEPTS には、各ウェイポイントの高度と予想到達時刻がより詳細に含まれる
- ICAO 経路には9つのウェイポイントしかなくても、ADEXP の拡張リストには21のウェイポイントが含まれることがある
- ICAO 経路の出発地と到着地は別フィールドにあるため、経路リストには再度含まれない
障害を生んだ重複ウェイポイント
- 問題の ADEXP ウェイポイント一覧には、地理的に異なる2つのウェイポイントが同じ designator を持っていた
- ICAO や他の機関は一意でないウェイポイント名を削減しようとしてきたが、世界には依然として重複名が存在する
- 最新の標準では、同じ識別子を持つウェイポイントは地理的に十分離れていなければならないと定めている
- この事例の2つのウェイポイントはいずれも英国外にあり、1つは経路前半、もう1つは経路後半にあり、約4,000海里離れていた
- 実際に特定された便 FBU731 の拡張飛行計画では、DVL というウェイポイントが2回現れる
- 1つは米国ウィスコンシン州の Devil’s Lake
- もう1つはフランス・ノルマンディーの Deauville
- 後者は
UN859 航路の展開過程で飛行後半に現れたものと整理されている
FPRSA-R の処理手順と失敗地点
- FPRSA-R は ADEXP ウェイポイントデータから英国空域 進入地点 を先頭から検索して見つける
- 続いて英国空域 離脱地点 を探し、その後 ICAO4444 セクションで対応する区間を見つけようとする
- ICAO 経路には空域離脱地点が必ず含まれている必要はない
- ソフトウェアは、離脱地点が ICAO 経路にない場合、ADEXP ファイル内の次に近い地点を使って再検索するよう設計されていた
- この事例では、ソフトウェアは ADEXP の次のウェイポイントをたどるうちに、ICAO 経路内に存在する 重複識別子 を見つけた
- しかしその識別子は、実際の英国空域離脱後のウェイポイントではなく、経路前半にある別の地理的ウェイポイントだった
- その結果、進入地点と離脱地点の順序または区間が有効でなくなり、英国空域に該当する ICAO 区間を抽出できなかった
- NATS の報告書はこの点を事案の root cause とし、サイバー関連の寄与は排除できると結論づけている
主系統とバックアップ系統が同時に停止した理由
- 安全重要ソフトウェアは、安全に継続できない場合に手動介入が必要な状態へ移行するよう設計されている
- FPRSA-R の主系統は、飛行計画の正しいデータを保証できないと判断し、critical exception を発生させた
- ログファイルをシステムログに記録した
- maintenance mode に入った
- C&M システムは主系統がもはや利用不能であることを検知した
- バックアップ系統は主系統障害時に処理を引き継ぐよう設計されていた
- 別ハードウェア、別電源、別データフィード上に配置されていた
- しかし同じ飛行計画に同じロジックを適用し、同じ結果として critical exception を発生させた
- ADEXP メッセージ受信から主系統とバックアップ系統の双方が maintenance mode に入るまで 20秒未満 だった
- 08:32 に自動飛行計画処理が停止し、その後は4時間のバッファ時間内で手動の飛行計画入力が必要となった
復旧手順と運用への影響
- 1st Line サポートチームは、専用 C&M システム、中央 C&M システム、運用チームからのフィードバックを通じて障害を認識した
- 初期対応は、中央 C&M システムからサブシステムを再起動する標準復旧手順だった
- 複数回の復旧試行が失敗した
- 2nd Line エンジニアリングチームが投入され、現場エンジニアを遠隔映像リンクで支援した
- 1st Line と 2nd Line がサービス復旧や正確な原因特定に失敗したため、Technical Design チームとサブシステム製造元の支援が要請された
- 製造元は低レベルのソフトウェアログ解析を通じて、障害を引き起こしたとみられる飛行計画を特定した
- その飛行計画を理解したうえで、制御され安全な形でシステムを復旧するための正確な手順を提供した
- 障害時には手動入力と部門間の手動調整手順が含まれていたが、手動手順へ切り替えると英国の交通流を減らすため航空交通管制上の制限を適用する必要があった
Frequentis AG と FPRSA-R
- FPRSA サブシステムは NATS に長年存在しており、2018年に既存システムが Frequentis AG の新しいハードウェアとソフトウェアに置き換えられた
- Frequentis AG はオーストリア企業であり、航空交通管制システムの供給企業の1つである
- この製造元の ATC 製品は約150か国で運用され、航空情報管理とメッセージ処理システム分野で世界的な地位を持つとされる
- Frequentis AG の採用ページには、航空交通管制システムに関連して
Ada, C++, Java, Python が登場し、Java が最も頻繁に見られる
ソフトウェアバグとテストの問題
- FPRSA-R は IFPS が受理した有効な飛行計画から、英国空域に該当する ICAO 区間を抽出できなかった
- ウェイポイント識別子はグローバルに一意ではなく、これは既知の問題である
- 重複ウェイポイントが非常に離れていれば、通常の飛行計画は依然として曖昧でない場合がある
- しかしソフトウェアはこの条件を堅牢に処理すべきだった
- NATS は、ICAO が管理するグローバルデータセットからこの事案に関連する少数の重複ウェイポイント名を削除する案を、英国政府を通じて検討できると述べている
- NATS の CEO である Martin Rolfe は BBC に対し、この事案は「1,500万分の1」の可能性だと語った
- このシステムは2018年に導入され、それまでに1,500万件の飛行計画を処理したと述べた
- 安全重要システムであるなら、飛行計画処理段階、とりわけ英国区間抽出のような重要ステップはテストされるべきである
- 重複ウェイポイント名を考慮しないテストでは、このバグを露呈できなかった可能性がある
- ランダムな飛行計画を大量投入する ファジング(fuzzing) は、システムを悪いフェイルモードに追い込む入力を見つけるのに役立った可能性がある
フェイルモードの問題
- 単一の飛行計画が FPRSA-R 自動処理システム全体を停止させ、その結果どの飛行計画も自動処理されなくなった
- より望ましいフェイルモードは、問題のある単一の飛行計画を別の低速キューに送り、人が手動で処理する方式である
- NATS は、すでに進行中または完了した対策として、IFPS と FPRSA-R の間のデータフローに特定のメッセージフィルタを追加し、この事案を引き起こした条件に合致する飛行計画を除外すると述べている
- FPRSA-R が停止した際、関連する飛行計画は低レベルのソフトウェアログでようやく特定された
- 飛行計画処理システムで特定の飛行計画処理エラーがシステム全体を停止させるなら、その飛行計画を含むアラートが監視チームへ即時に送られるほうが適切である
- NATS は、同様の状況が再発した場合に FPRSA-R を迅速に復旧できる運用手順を整備し、技術オペレーターが新手順を実施できるよう訓練を受けたと述べている
- 強化された監視と追加のエンジニアリング専門人員も運用を監督する予定である
形式検証の可能性
- この事案の該当段階とシステムで 形式検証 が使われた痕跡は明確ではなく、報告書にも言及はない
- 形式検証やモデル検査は、この種のバグを減らす助けになった可能性がある
- ただし大規模システムのエンドツーエンドの形式検証はまだ初期段階であり、形式検証を一部利用していたとしても欠陥コードが運用環境に入る可能性は残る
- 最終調査結果が出れば、実際にどのような検証方式が使われたのかさらに分かるかもしれない
安全性と公開報告
- 英国上空の航空機は、事案の全期間を通じて安全に維持されていた
- 経験豊富な航空交通管制官が、既知の飛行計画、無線、レーダー、視認を通じて航空機を監視していた
- 結果として生じたのは人命リスクではなく、離陸できる便数が大きく減るか、英国空域を避けて迂回しなければならない状況だった
- NATS は便数を減らす措置を取り、安全を維持した
- 公開された報告書はかなり透明で詳細であり、重要インフラにとってこうした報告は重要である
- Ryanair の Michael O’Leary はこの報告書を「rubbish」と批判し、航空業界への影響を過小評価していると述べたが、初期報告書の範囲は NATS の失敗の程度を分析することにはなかったとの評価もある
より堅牢な実装の方向性
- 問題は2つのシーケンスのウェイポイントを扱うことにある
- ADEXP: 全ウェイポイント一覧
- ICAO: ADEXP ウェイポイントの部分列
- ICAO 計画には空域進入・離脱地点が必ず含まれるわけではないため、英国空域に該当する ICAO の最小連続区間を見つける作業は単純ではない
- 誤ったアルゴリズムの問題は、ICAO データと ADEXP データを同時に指すポインタを操作しつつ、明確でない不変条件をコードの外に置いていた点にある
- 提案されたアプローチは、まず ICAO と ADEXP データを1つの Combined 飛行計画構造へ照合し、その後で英国区間を抽出するというものだ
- 取り得るすべての reconciliation を計算して曖昧な場合を検出する
- reconciliation が 0 件なら ICAO と ADEXP を照合できない
- 複数件なら曖昧なので手動処理対象にできる
- Haskell の実装例は、
NonUkPlan, CannotReconcileIcaoAdexp, AmbiguousReconciliationsOfIcaoAdexp のエラーを明示的に扱う
- 例では、ADEXP 一覧に重複識別子
Q があっても、ICAO と ADEXP のデータが曖昧なく照合できれば正しい英国区間を返す
- 全コードは uk-portion-of-ICAO にある
1件のコメント
Hacker Newsのコメント
飛行計画のクエリに地理的に分離されたスコープ制限を入れ忘れた、ということだ。以前、飛行ナビゲーションシステムを作っていたときにこのバグを知っていたし、実際に見たこともあり、このバグを避けるためにジオフェンスを入れるという仕様に従ったことがある
「バックアップシステムが同じロジックを飛行計画に適用し、同じ結果になった」という箇所が問題だ。ソフトウェアでは、バックアップシステムは別のロジックを使うべきだ
以前Boeingで757の水平安定板トリムシステムを扱っていたとき、トリムを作動させる配線に2台の航空電子コンピュータが接続され、比較器を介してつながっていた。2つの箱が一致しなければ、両方とも権限を失う構造だった
2つの箱は、異なるアルゴリズム、異なるプログラミング言語、異なるCPU、ファイアウォールで分離された別チームのコードで設計されており、一方のバグがもう一方を同じ形で壊さないようにする意図があった
航空管制システムは少なくとも2oo3[1]、つまり独立して開発された3つのシステムのうち常に2つが一致しなければならない構造であるべきだ。そうすれば1つのシステムが失敗しても残り2つが運用を継続でき、航空業界の可用性に影響しない
人間をバックアップに置くのは、人員と複雑さのため不可能だ。航空管制システムはIFR[2]とCVFR[3]の条件下で分離管制を提供できなければならない
[1] https://en.wikipedia.org/wiki/Triple_modular_redundancy
[2] https://en.wikipedia.org/wiki/Instrument_flight_rules#Separa...
[3] https://en.wikipedia.org/wiki/Visual_flight_rules#Controlled...
J. Gall
NATSで同じような効果を生んだ別の問題もあったと記憶している。一次システムが倒れて二次に切り替えたが、二次もまったく同じ理由で倒れた
フェイルオーバーは、問題が一次システム自体にあり、ソフトウェアそのものではないと分かっているときだけ行うべきなのだろう。単に切り替える方式は、実際に何をすべきか判断できるだけの十分な情報が表に出ていなかったという印象を強めるだけだ
さらに気分が悪くなるのは、「ValidateFlightPlan」のようなメソッドがなく、何らかの理由でパースできなければエラーを投げ、そのエラーを非常に単純に処理する経路がなかったという点だ。外部入力ハンドラを見ながら「壊れるような悪い入力が来たらどうする?」と考えないプログラマーがいるのだろうかと思う
本当の安全機能は、手動処理が必要になる前に4時間の猶予があることだ
航空における中核的な安全統制は、「そもそもどう壊れないようにするか」よりも、「何らかの理由でこれが壊れたら何をするか」に近い
プログラミングスタイルが非常に命令型で、説明だけ見ると、手続きがテキストファイルからパースしたデータ構造ではなく、飛行計画のテキスト表現を直接扱っているように聞こえる。実際にそうならかなり心配だが、説明の仕方のせいかもしれない
この説明どおりなら、単にテキストに正規表現や部分文字列マッチングをかけていて、クラスやオブジェクトやデータ構造がない構造でも驚かない。英国の航空全体が依存する、書き直しも置き換えもできない数十年もののCコードである可能性も考慮すべきだ
一次システムが整数オーバーフローで失敗し、同一の二次システムも同時にオーバーフローした。迎角が増加し、ブースターが分離し、ロケットが爆発した
[1] https://en.wikipedia.org/wiki/Ariane_flight_V88
なぜ失敗した飛行計画だけを人間によるレビュー待ちキューに入れて、残りのフライトの処理を続けられなかったのか分からない。その「機能」がなかったという点がいちばん理解しにくい
「絶対に起きてはならない」エラーが発生すると、システムの何が間違っているのか、影響がどれほど大きく広いのか分からない。今回のように続行してもよかったのかもしれないが、ソフトウェアに致命的な新しいバグが生じて、ほかのすべての飛行計画をひそかに汚染し、人を死なせる可能性もある。続けても安全か分からないなら、止めるしかない
問題のある特定の飛行機が離陸しないよう止められるなら、システムを動かし続けてもよいが、すでに空中にいるなら話は変わる
「英国空域に入る航空機が航路上にいるが、いつどこから入るか分からない。その航空機の位置が分かるまで追加の飛行計画を止める」という判断は、完全に不合理とはいえない
飛行計画を本当に処理できないなら、英国に到達する前に当該機を迂回させて着陸させるような解決策が合理的かもしれないが、そうしたことは結局、手動介入を待たなければならない
どんなシステムも誤作動し得るので、重要なのはよい形で誤作動し、担当者がその状況に備えていることだ
単一の飛行計画が問題を起こし、FPRSA-Rシステム全体が落ちて、飛行計画がまったく処理されなくなった。飛行計画1件に問題があるなら、人が手動処理する別の低速キューに移すべきだ。NATSも「すでに実施した、または進行中の措置」の中で、IFPSとFPRSA-Rの間のデータフローに、該当条件の飛行計画を除外するメッセージフィルターを追加すると認めている
これが既知のエラーとして処理されるべきだったという意見は妥当だが、広く言えば「バグのないコードを書くべきだった」という話に近い。構造体としてパースしていたとしても、選択キーがあると仮定したコードで突然KeyErrorが飛び出したのと同じかもしれない
こうした事態の事後分析と改善は、予測できない未処理の不明なエラーがいつか発生するという前提に立ち、そのときどうすればよりよく扱えるかを扱うべきだ。バグの解決策はバグを直すことだが、大規模障害の原因は、合理的な時間内に実行できない災害復旧計画だった。どんなプログラミング慣行、スタイル、言語、ツールを使っても、同程度の事件は最高の開発者たちであっても、いつか確率1でまた起きる
コードから見ると、基盤となる航法ウェイポイントデータベースの整合性失敗のように見えたなら、飛行計画の処理を中断する判断ははるかに理解できる
たとえばコードがウェイポイントと航路のストアに「この航路が英国空域を出るウェイポイントを見つけて」と問い合わせ、そのウェイポイントを含む航路区間を見つけたうえで、その区間は英国空域を通過すると断言したのに、その断言が失敗したなら、これは飛行計画の問題ではなく、航路データに埋め込まれた前提が破られたように見えるかもしれない
ある意味では、実際に致命的なバグである可能性もある。この事件は、アルゴリズムがデータについて置いた仮定が間違っており、潜在的に誤った答えを返し得ることを示している
関連記事
偶然同じウェイポイント名だったために英国の航空管制システムがだまされた - https://news.ycombinator.com/item?id=37430384 - 2023年9月、コメント64件
悪い飛行計画データが英国の航空管制障害を引き起こした - https://news.ycombinator.com/item?id=37402766 - 2023年9月、コメント20件
NATSの航空管制インシデント報告書が根本原因と解決策を詳述 - https://news.ycombinator.com/item?id=37401864 - 2023年9月、コメント19件
英国の航空管制ネットワーク障害 - https://news.ycombinator.com/item?id=37292406 - 2023年8月、コメント23件
Eurocontrolがすでに受け入れたフランスの飛行計画のせいにしたという事実は、彼らがソフトウェアの動作をきちんと理解していなかった証拠だ。そしてオーストリアの会社も、集中的なテスト不足について責任の一端を負うべきだ
すばらしい記事。読んでみると要点はこうだと思う
世界中で使われるウェイポイント名は一意ではなく、混同を避けるための一種のつぎはぎとして、最新の標準では同じ識別子を地理的に十分離して配置するよう求めている。それでも、1つの航路内で同じウェイポイント名が異なる位置を意味することはあり得る
ソフトウェアはその可能性を考慮しておらず、航路計算に失敗し、「致命的例外」を投げて「保守モード」に入った。つまり死んだ
バックアップシステムが引き継いだが、同じデータで同じバグを踏んでやはり死に、サポート要員は苦労した。結局、ソフトウェア供給元に連絡して初めて、原因を示す低レベルログを見つけた
退役した空軍パイロットの友人がCranfield Universityを卒業したのだが、ここは英国を代表する航空宇宙工学の大学院機関で、教育・研究用の自前の空港もある[1]。その友人はCranfieldでOSを学んだと言っていたが、今になって理由が分かった
他のコメントを見ると名前空間の標準はすでにあるが、NATS/ATCが使っていないようだ。今回の件を機に、ぜひ使い始めてほしい。トップコメントはジオフェンシングのバグに触れていたが、NATS/ATCが正しい名前空間を使っていたなら、ジオフェンシングはそもそも不要だった可能性が高い
[1] Cranfield University:
https://en.wikipedia.org/wiki/Cranfield_University
「説明だけを見ると、手順はテキストファイルからパースしたデータ構造ではなく、飛行計画のテキスト表現を直接扱っているように聞こえる。実際にそうならかなり心配だが、説明の仕方のせいかもしれない」
航空業界の仕事ではこういうやり方はよくある。プログラマーにドメインモデルやパースについて聞くと、ぽかんとした顔をされることが多い。検証コードを好み、検証できなければただ諦めるのを好む。全部が間抜けなデータパイプラインで、現実世界で起きる活動をモデル化するコードはまったくない
どのシステムにも、動作を持つ「飛行計画」型やウェイポイント型の集合のようなものはない。型があったとしてもC的な観点での文字列構造体で、その構造体メンバーにアクセスされるたびに、一度どころか毎回パースされる。記事が言うように「プログラミングスタイルは非常に命令型に見える」で合っている
悪い入力で死ぬのはよくないが、仕様もないのに検証されていないデータを解釈しようとするのは、その後の理解の不一致や互換性問題、予期しない境界条件を招きやすい。完全にテストされた全ケース対応システム、不正入力シミュレーションツール、パーサーとその結果を使うすべてのコードの形式検証には、誰も費用を払いたがらない
すでに非準拠・レガシー・バグ持ちのデータ送信機や、インターフェース意味論・タイミング複雑性のせいで問題は多い。形式やエンコーディングが誤ったデータに賢く対応しようとすると、さらに危険になる
仕様どおりに動くシステムを作るだけでも難しく高価だ。仕様にない動作をより寛容に受け入れる微妙な変種は、バグを招く行為か、購入価格の基準を超えてしまうより高価なシステムを作る行為である
「英国航空管制:フランスのエラーが障害を引き起こしたのか調査」
当然違うだろう。英国のシステムなのに、どうしてフランスの航空会社のせいになるのか?こういうシステムは冗長性を備えたフェイルセーフ構造であるべきだ
項目が1つ悪ければ、それを拒否して続行するだけで十分だったかもしれない
思い出したくない一日だった。本来なら2時間で着く目的地に15時間かかった
電車、バス、また電車に乗り、チケットを予約してから30分後には2日分がすべて売り切れていた