ニュース

世界中の「Firefox」が一時的に使用不能になった問題について、Mozillaが詳細を明かす

ロードバランサ―の設定とHTTP/3接続に関する問題が引き金に

Mozillaの公式ブログ「Mozilla Hacks」

 米国時間1月13日、世界中の「Firefox」が一時的に使用不能になった。この問題はクラウドサービス側の設定変更で間もなく解消されたが、そこでは一体なにが起こっていたのだろうか。Mozillaの公式ブログ「Mozilla Hacks」に2月2日付けで掲載された記事で、その詳細が解説されている。

 開発チームに「Firefox」が接続試行中にハングアップするという報告が寄せられるようになり、クラッシュレポートでもハングアップが急増していることが確認できてからも、Mozillaのエンジニアは原因をなかなか特定できないでいた。当初は、最近実施された「Firefox」のアップデートに疑いがかけられたものの、調査を進めても問題を引き起こす可能性のある変更は見当たらなかった。

クラッシュレポートでもハングアップが急増していることが確認

 しかし、調査の過程で「Firefox」の内部サービスの1つに対するネットワーク要求でハングアップが起こっていることが突き止められた。そこで、ロードバランシングに使用しているクラウドプロバイダーの1社が「目に見えない」設定変更が行われたのではないかとの疑いが浮上する。

 ロードバランシングとは、サーバーの負荷が一部に集中しないように分散する仕組みのこと。「Firefox」はアップデートの配信やテレメトリ(利用状況の遠隔測定)、証明書の管理、クラッシュレポートの送信などといった機能を実現するため、バックエンドで多数のサーバーを運用しているが、この負荷を均等にするため導入されている。

 Mozillaのエンジニアがロードバランサ―の設定を調査したところ、変更された箇所は見当たらなかった。しかし、ログを調べてみたところ、テレメトリサービスのロードバランサ―で、それまでは行われていなかったHTTP/3接続が行われていたことが判明したという。そこで9時12分(協定世界時)、「Google Cloud Platform」(GCP)上でHTTP/3を明示的に無効化したところ、ユーザーのブロックが解除されたという。

 GCPのHTTP/3サポートは「有効」「無効」「自動(既定)」のうち「自動」、つまりGoogleに任せるように設定されていたが、1月13日07:28(協定世界時)に告知なく有効化されていたようだ。

 これでひとまず問題は解消したが、根本的な原因はまだ特定できていない。そこでさらにデバッグを進めた結果、この問題を引き起こした「特別な要素」が発見された。

「Firefox」の内部構造

 「Firefox」のHTTP/3接続は、すべてネットワーキングスタック「Necko」を経由する。しかし、ネットワークへアクセスする必要のあるRustコンポーネントは、「Necko」を直接使うのではなく、「viaduct」と呼ばれる中間ライブラリを挟んで「Necko」を呼び出す仕組みになっている。

 HTTP/3接続はリクエストサイズを決定するため、「Content-Length」ヘッダーを必要とする。「Necko」はこのヘッダーが存在するかどうかをチェックし、存在しない場合は自動で追加する。

 ところが、「Necko」のチェックでは大文字と小文字が区別されない。一方で、HTTP/3接続においては大文字と小文字が区別される。

 「Necko」は「Content-Length」ヘッダーを追加する際、大文字と小文字を正しく挿入するため、この違いは通常、問題とならない。しかし、「viaduct」を通過するリクエストは「Content-Length」ヘッダーを小文字に変換してしまう。そのため、「Necko」のチェックをすり抜けてしまうが、実際のHTTP/3接続では「Content-Length」ヘッダーを見つけられず、送信するコンテンツがないとして予期せず終了する。このおかげで、コードはエラーを返すどころか、無限ループに陥る。すべてのネットワークリクエストは1つのソケットスレッドを経由するため、このループはそれ以上のネットワーク通信をブロックしてしまい、その結果「Firefox」はWebコンテンツを読み込めずに無反応となってしまった。

 Rustベースの「Firefox」コンポーネントのうち、ネットワークスタックを利用しており、かつ「Content-Length」ヘッダーを追加するのはテレメトリコンポーネントだけだ。そのため、テレメトリを無効化している「Firefox」ではHTTP/3接続のエラーは幸運にも発生しなかった。しかしこれはたまたまで、根本的な原因は「Necko」と「viaduct」の関係にあったといえる。

 Mozillaはこのインシデントからいくつかの教訓を得たとして、今後はこのような問題が発生しないようにすべてのロードバランサ―を調査して設定を見直すとともに、異なるHTTPバージョンでより多くのシステムテストを実施するとしている。