ぼちぼち日記

おそらくプロトコルネタを書いていることが多いんじゃないかと思います。

HTTP/2.0のALPN利用に伴うSSL負荷分散装置の不具合にご注意下さい

1. はじめに、

ただ今IETF-88@バンクーバーの開催が真っただ中です。スノーデン事件の余波もあり、インターネット技術(特にセキュリティ関連)の議論は熱くなっています。

ちょうど今朝未明(バンクバーでは11/5朝)に HTTP/2.0の標準化を進める httpbis ワーキンググループとセキュリティエリアの合同セッションが開催されました。合同セッションでは、ヘッダ圧縮技術(HPACK)のセキュリティや、HTTP接続(HTTPSではない)で通信の暗号化を行ったらどうか、といった興味深い議論が行われました。このうち将来HTTP/2.0の展開に重要な ALPN(Application Layer Protocol Negotiation) は、このミーティングで最終的な仕様を確定させる段階での議論でした。議論の中で、ALPNの導入によってブラウザから既存の実サービスへの接続に(少なからず)影響が発生するのではないかという懸念が指摘されました。(参照: 「Please update F5/BIG-IP firmware (07 Oct 2013)」「ALPN concerns」「ALPN」
実はALPNはまだ仕様確定前ですが、既に Chrome や IE11のブラウザに実装され、最近Googleのサービスで実利用され始めています(後述)。現在、この不具合を回避するようブラウザ側で工夫されていますが(後述)、いずれは顕在化する問題なので現時点で注意喚起を兼ねて「ALPN利用に伴うSSL負荷分散装置の不具合」について書きたいと思います。

2. ALPN(Application Layer Protocol Negotiation)とは、

HTTP/2.0仕様では、クライアントとサーバ間で合意してHTTP/2.0接続を開始する方法は、3種類の2段階で規定されています。詳しくは、「新たな技術仕様・要素とは?HTTP/2.0相互接続試験参加レポート(技術解説編)」をお読みください。TLSによるオーバヘッドを加味しても性能や効率が良い接続方法として、TLS+ALPN拡張の手法はHTTP/2.0導入後に最も主流となる接続方法になるだろうと予想されます。ALPNの仕組みについて簡単に下図で示します。

ざっとした流れは、

  1. TLSのハンドシェイクでクライアントからサーバへClientHelloを送信する際に、TLSのALPN拡張フィールドにアプリケーションで利用するプロトコルリストを含めて送信する。
  2. サーバ側は、クライアントから受け取ったプロトコルリストから最適なプロトコルを選択して ServerHello のTLSのALPN拡張にそのプロトコル名を付与して返信する。
  3. TLSのハンドシェイクが終了したらALPNのやり取りでサーバ、クライアント間で合意したプロトコルで通信を継続する。

になります。
現在実サービスで利用されているSPDYでは、同様の仕組みとしてNPN(Next Protocol Negotiation)が試験仕様として使われていました。しかし、

  • NPNではクライアントがプロトコルを選択するが、ALPNではサーバがプロトコルを選択する。サーバ側が選択権を持つのは他のセキュリティ技術(暗号種類の決定等)で行われているやり方なので、そのポリシーに従う。
  • NPMは3回クライアント、サーバ間でやり取りが発生するのに対し、ALPNは2回で済むので効率的である。

といった理由から、最終的に ALPN が仕様候補として採択されました。

3. ALPN利用による負荷分散装置の不具合とは

ALPNは、先述の通りクライアントがプロトコルリストをサーバに送信します。通常プロトコルリスト中に複数のプロトコル名が記載され、サーバは複数の選択肢の中から最適なプロトコルを選びます。そのためALPNを使った ClientHello のデータがNPNに比べて増大してしまうことになります。(NPNでは、最初TLS拡張領域のデータが空のClientHelloを送信する。)
ここで大きな問題は、現在インターネット上で実利用されている負荷分散装置には、かつて255バイト以上のClientHelloを受信するとTLS接続がハングアップしてしまうという不具合を持つものが存在しているようです(しかもそれなりの数で)。ブラウザから見るとサーバからエラーが返るのではないためタイムアウトまでずっと待ち続けなければなりません。これはブラウザ・サーバ両者にとって不幸な状態です。

もっともClientHello のデータ量が肥大化するのは ALPNだけではありません、多くの暗号名やSNI(Server Name Indicator)に含まれる長いFQDN等が存在すれば 255バイトを超える可能性があります。そのためブラウザベンダーは、これまで ClientHelloを255バイト以下に抑えるよういろいろ苦労して工夫をしてきました。今後ALPN が利用されると、そういうワークアラウンドも対応できなくなるのではないかとの懸念がブラウザベンダ側に出てきても当然です。

4. Googleサービスで、ALPNの試験利用が始まった

今回のセッションで、GoogleのサービスでALPNの試験利用が始まっていることがアナウンスされました。試しにALPN対応のWiresharkを使って Chrome Canary(32.0.1700.4)から https://www.google.co.jp/ への ClientHello のデータを見てみます。

www.google.co.jp 宛の ClientHello に ALPN拡張フィールドが含まれており、プロトコルリストに5種類プロトコル名が含まれています。驚くことに ClientHello のバイト数は230バイトで255バイト以下に抑えられています。これなら現状、先の不具合をなんとか回避できています。

5. 今一度サイトの確認を!

Mozillaの調査では、TLSハンドシェイクが途中でハングするような不具合を持つサイトは、おおよそ2.9%程度になると結果が出ています(https://bugzilla.mozilla.org/show_bug.cgi?id=733647#c48)。また先述のChrome のネットワークセキュリティスタックを開発するエンジニアのブログ(「Please update F5/BIG-IP firmware (07 Oct 2013)」 )では、不具合の確認方法と彼が調査した不具合が発生しているであろうドメイン名が一部公開されています。(トップ200サイト分)

もし、このブログをお読みの方で Big-IPのversion 10.2.4より古いファームウェアを利用している場合は、是非アップデートを検討していただくようお願いします。

筆者が https://www.imperialviolet.org/2013/10/07/f5update.html で指摘されているドメインを調べたところ、 .jp ドメインのサイトは、20 程存在しました。いくつかのサイトを直接調べたところ、必ずしもこのリストのドメイン名で不具合が発生しているわけではないようです。もしかするとサブドメインのサイトが対象であったり、たまたまネットワーク障害などで調査の誤認識であった可能性もあります。ただ不具合が発生した場合、ユーザ側・サイト側での双方切り分けが難しいことが予想されます。そのため 20の .jp サイトのドメイン名を下表に記します。該当サイトのインフラ担当の方が見られましたら一度調査していただくことをお勧めします。 もし全く問題がないのでしたらこのリストから消去しますので本ブログへのコメントまで連絡をお願いします。(全くもって不適切というのであれば表自体を削除します。) また本リストに掲載されていないから不具合がないということを保証しているわけでありませんのでご注意ください。

次世代の HTTP/2.0 の利用は間近です。ALPN と同様に仕様がある程度固まったら実環境でどんどんHTTP/2.0の試験利用が進んでいくでしょう。最新技術には全く関係ないからと思っていると、その時にあわてることになりかねませんので事前に確認していただくことを心がけましょう。

index ALPNで不具合を含む可能性がある.jpサイトのドメイン*1
1 allabout.co.jp
2 zozo.jp
3 plala.or.jp
4 yaplog.jp
5 jal.co.jp
6 mizuhobank.co.jp
7 diamond.jp
8 jorudan.co.jp
9 ecnavi.jp
10 prcm.jp
11 tsite.jp
12 jreast.co.jp
13 ismedia.jp
14 askul.co.jp
15 golfdigest.co.jp
16 belluna.jp
17 tsutaya.co.jp
18 capcom.co.jp
19 become.co.jp
20 research-panel.jp

*1:繰り返し書きますが、これらのサイトに必ずしも不具合が存在すると確定されているわけではありませんのでご注意ください。