Firefoxが突然ページを表示できなくなった原因や当時の対応について公式ブログが解説
2022年1月13日、ウェブブラウザのFirefoxでウェブページが表示できなくなる不具合が生じました。一体なぜこのような事態が生じたのかについて、Firefoxなどの技術情報を伝えるMozillaの技術ブログ・Mozilla Hacksが解説しています。
Retrospective and Technical Details on the recent Firefox Outage - Mozilla Hacks - the Web developer blog
Firefoxで発生した2022年1月13日の不具合については、ウェブサイト閲覧時の通信で使われるプロトコル・HTTP/3に関するバグが原因だったことが報じられています。今回のブログを投稿したクリスチャン・ホラー氏は、このバグが誘発された理由やMozillaの対応について、さらに詳細な説明を行っています。
Firefoxが突然ページを表示できなくなった原因は結局何だったのか? - GIGAZINE
ホラー氏はブログの中で、Firefoxにはいくつかの内部サービスを処理するための複数のサーバーと関連インフラストラクチャーがあり、これにはアップデート・テレメトリ・証明書管理・クラッシュレポートなどの機能が含まれると説明しています。Firefoxのインフラストラクチャーは、ロードバランサーを使用してサーバー間の負荷を均等に分散する、Google Cloud Platform(GCP)などのクラウドサービスプロバイダーによってホストされているとのこと。
GCPでホストされているサービスの場合は、ロードバランサーがアドバタイズするHTTPプロトコル関連の設定項目があります。HTTP/3のサポートステータスは「Enabled(有効)」「Disabled(無効)」「Automatic (自動)」から選択可能となっており、Firefoxではデフォルトの「自動」に設定されていました。
そして、GCPは2022年1月13日7時28分(協定世界時)に、告知なしでHTTP/3をデフォルトのプロトコルにする変更を展開しました。Firefoxの設定は「自動」だったため、これまでは接続する際にHTTP/2を使用していたサービスインフラでも、自動でHTTP/3に切り替わってしまったとホラー氏は述べています。
デフォルトのプロトコル変更についてGCPからの告知がなかったため、MozillaはFirefoxの内部サービスでHTTP/3が使用されるようになったことを知りませんでした。ところが、この変更が展開された直後にクラッシュレポートやMozilla内外のレポートを通じて、Firefoxのクラッシュが急増していることに気付いたそうです。Firefoxのクラッシュレポート数の推移を示した以下のグラフを見ると、7時30分頃を境にクラッシュレポートが急増していることがわかります。
原因を調査したMozillaは、クライアントがFirefox内部サービスの1つでネットワークリクエストが停止していることを発見。この時点では問題の原因や範囲について不明だったため、さらに分析したところ、Firefox側ではこの問題を引き起こす可能性があるアップデートや構成変更を行っていないこともわかりました。
そこで、「クラウドサービスプロバイダーによってある種の『目に見えない』変更が行われ、ロードバランサーの動作が何らかの形で変更されたのではないか」と考えたとのこと。ログを調査したところ、これまでHTTP/2接続を提供していたテレメトリサービスのロードバランサーが、なんらかの理由でHTTP/3接続を提供していることが判明しました。そこで9時12分に、GCPで明示的にHTTP/3を無効にしたところ、ユーザー側の問題は解消されたとホリー氏は述べています。
Firefoxの問題が生じた根本的な原因を調査したところ、HTTP/3接続が経由するネットワークスタックの「Necko」と、ネットワークへの直接アクセスを必要とするRustコンポーネント呼び出す中間ライブラリの「viaduct」という要素が関わっていることがわかったそうです。
Neckoの内部では、HTTP/3アップロードリクエストの際に「Content-Length」ヘッダーの存在をチェックし、存在しない場合は自動でヘッダーが追加されます。下位レベルのHTTP/3コードは、このヘッダーに基づいてリクエストするデータのサイズを決定しています。ところが、リクエストが最初にviaductを通過する場合は、各ヘッダーが小文字になった状態でNeckoに渡されるそうで、ここに問題があるとのこと。
Neckoのチェックでは大文字と小文字の区別がされませんが、下位レベルのHTTP/3コードでは大文字と小文字を区別します。そのため、Content-Lengthヘッダーを追加されたコードがviaductを経由する場合、Neckoのチェックではヘッダーが検出されるものの、HTTP/3コードはヘッダーを検出しないという矛盾が発生します。この食い違いが原因となって、「Neckoはリクエストが完了したものと判断しているにもかかわらず、実際のリクエスト本文は未送信のまま」という状況に陥り、無限ループが生じてしまった結果、ネットワーク通信全般がブロックされてウェブページが表示できなくなったとホリー氏は解説しています。
ホリー氏は今回の事態から、いくつかの教訓を学んだと述べています。
・クラウドサービスプロバイダーとの連携を深める
GCPがデフォルトでHTTP/3を導入することを発表していれば、インシデントのリスクを完全になくすことはできなかったとしても、被害を軽減できた可能性があります。そのため、Mozillaは状況を改善するためにGCPと協力しているとのこと。
・設定を明示的にする
今回の問題が起きた原因の1つには、MozillaがGCPのロードバランサー設定を「有効」でも「無効」でもなく「自動」にしていたことが挙げられます。Mozillaは今後同様のミスを防ぐために、すべてのサービス構成を見直しているとしています。
・構成とコンポーネントのテスト
今回問題が起きたFirefoxデスクトップにおけるHTTP/3とviaductの組み合わせは、Mozillaがテストした組み合わせではなかったとのこと。構成とコンポーネントの可能な組み合わせをすべてテストすることはできないものの、Mozillaは異なるHTTPバージョンでより多くのシステムテストを実行する必要性を認識しているそうです。
ホリー氏は今回のブログの末尾で、「今回の一件から可能な限り学ぶことは、私たちの製品の品質向上に役立ちます。クラッシュレポートを送信したり、バグ管理フォーラムのBugzillaで協力してくれたり、他のユーザーが問題を回避するのを手伝ってくれたりしたすべてのユーザーに感謝します」と述べました。