これからドンドン使われていくSNIについて

SNIとは

元々SSL通信は1つのIPアドレスに対して、1つの証明書が前提になっていました。というのもSSLでは暗号化されているため、1つのIPアドレスに対して複数の証明書を持っていた場合、リクエストが来たときにどの証明書を使えばいいか判断できないからです。
しかしこれだとどう考えてもつらいことが分かります。昨今の流れとして常時SSL通信が当たり前の世界になりつつあります。すべてのドメインに対して全てのIPアドレスを用意するのは特にIPv4では現実的ではありません。
そもそもHTTPではVirtual Hostを使って、1つのIPアドレスで複数のドメインのサイトを扱うことがとても一般的です。
そこで有用なのがSNIです。SNIは最初の通信時に今から通信したいサーバーネームをサーバーに平文で渡すことで、通信したいSSL証明書を指定できます。
SNIを使うことでHTTPのVirtual Hostと同じようにHTTPSを扱うことが出来ます。これにより追加でサーバーやIPアドレスを用意せずにHTTPSのサービスを追加できるので、低コストにHTTPSのサービスを大量に運用することができます。
nginxの場合、複数の証明書の設定を書いた場合、自動的にSNIを使って証明書を選択するようになります。SNIに対応していない端末からのリクエストの場合、443番ポートのdefault_serverの設定で指定されている証明書が使用されます。

SNIに対応していない端末について

SNIをサポートしていない端末で代表的なものは以下のものがあります。

  • Windows XP上のIE(Chromeは大丈夫)
  • Android2.3.*

Server Name Indication — Wikipedia

GAで過去一ヶ月のsession数を元に私が関わるサービスで、それぞれのユーザー数を取ってみました(2017/05現在)。

PC内でXPかつIE 0.04%
スマートフォン内でAndroid2.3.* 0.2%

SNIに非対応なブラウザを使用した場合でも、『証明書のエラーを無視する』的な質問にokと答えると普通に見れるようになるはずです(Android2.3は検証済み。XPは実機がないので未確認)。

ちなみにAndroid2.2以下はSHA256の証明書に対応していないため、既にほとんどのWebサービスをまともに見れません。現在ではSHA128の証明書は手に入れる手段はありませんし、危険なので使わないよう呼びかけられています。

SANについて

SANというものもあります。SANを使うことで1つの証明書で複数のドメインを扱うことが出来ます。Googleの証明書がすごいことになっているのでおすすめです。

Image for post
Googleの証明書

証明書1つの値段より、SANに加える方が一般的に高いのでそこは少し考えた方が良いですが、基本的にSANに加える方針で問題ありません。

HTTP2の落とし穴

実はワイルドカード証明書やSANのように複数のドメインを取り扱える証明書を使用してかつ、HTTP2を有効にしたときに思わぬ罠があります。

HTTP/2 のコネクション再利用について確認してみる — ブログのしゅーくりーむ

HTTP2ではコネクションを極力再利用して、高速に通信を行おうとします。コネクションが再利用できるかどうかをその証明書を使用して通信できるかどうかで判断を行う実装をしても良いということになっています。その場合DNSは引きません。

しかし画像配信とアプリケーションのフロントサーバーは別のサーバーで行うことも多いでしょう。画像配信の場合、オリジナルサーバーのレスポンスをキャッシュする必要があるなど、普通のフロントサーバーとは性質が異なるためです。その場合同一の証明書を使い回していると意図しないリクエストが来て、nginxのdefault_serverの設定が動いてしまうことがあります。

実は以前Firefoxで自分が関わるサービスを見れなくなりました。Firefoxは同一の証明書のコネクションを使い回す仕様を実装しています。そのサービスはフロントサーバーと画像配信サーバーが同じ証明書を使って別サーバーで行っていました。Firefoxが画像配信サーバーのコネクションに対してサービスのリクエストを送ったため、nginxのdefault_serverの設定が動いて403ページがユーザーに見えていました。

この問題を解決するために443番ポートのdefault_serverでステータスコード421を返すようにしました。ただこれをやると折角HTTP2を使っているのに、421を受け取る度にコネクションを繋ぎ直すようになるのでHTTP2の意味が減ります。

HTTP2のクライアントはSNIに対応している事が保証されています。HTTPSが必須かつ、同じ証明書ならコネクションを使い回そうとするHTTP2の仕様的にSNIはメリットが大きく、これから広く使われるようになると考えています。

まとめ

これから常時SSL通信が一般になればなるほど、SNIが広く使われるようになるでしょう。現在ワイルドカード証明書やSANを使用しているケースでも、同じ証明書のコネクションを使い回してもよいという仕様があるHTTP2では、ドメイン毎に証明書を用意してSNIを使用して配信する方が楽になる可能性もあります。SNIのことを覚えておいて損はないでしょう。

Written by

将来の夢は隠居です

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store