1台のWEBサーバーにバーチャルホストを設定して複数のWEBサイトを運営することはよくあることです。バーチャルホストとは1つのIPアドレスを複数のドメインで共有する技術のことです。ここでバーチャルホストの仕組みをおさらいしておきます。
WEBサーバーではxxx.comとyyy.comのドメインを運営しているものとします。
①ブラウザがxxx.comにアクセスをします。HTTP1.1以降の仕様ではHTTPヘッダにHostフィールドが必須となっているためブラウザはHostフィールドにドメイン(ここではxxx.com)を設定してWEBサーバーにリクエストを送ります。
②WEBサーバーはリクエストを受け取りHostフィールドを取得します。Hostフィールドに設定されたドメインを参照することにより、どのドメインへのアクセスかがわかります。
③バーチャルホストの設定ファイルをもとにドメインのマッチングを行い、HTMLファイルの取得(もしくは生成)をします。
④WEBサーバーは該当するWEBサイトのHTMLファイルをブラウザに返却します。
今まではこれで問題なかったのですが近年は常時TLS化が進んだ影響でこの仕組みではドメインが判断できなくなりました。どういうことかというと、TLSによりHTTPリクエストが暗号化されているためWEBサーバーのほうでHostフィールドが判断不能になりました。
そこでこの問題を解決するために導入された仕組みがSNI(Server Name Indication)です。どうやるかというと、暗号化されたHTTPリクエストとは別に「Hostフィールドに該当する情報」をブラウザからWEBサーバーに送るようにしています。このやりとりはTLSのハンドシェイク時に行われます。
SNIはブラウザとWEBサーバーが対応していれば良いためインターネットを利用する人が特に意識をする必要はありません。常時TLS化が一般的になってきた現在ではほとんどのブラウザがSNIに対応済みです。WEBサーバー側はTLSのハンドシェイクにOpenSSLを利用している場合、0.9.8以降で対応しているようです。
ちなみにですが、Hostフィールドに該当する情報をTLSのハンドシェイクの中のどこでやりとりしているのか、どんな感じで設定しているのかを確認しようと思い、Wiresharkを使ってキャプチャしてみました。以下がキャプチャした結果です。通信相手のサーバー情報は伏せています。
どうやらブラウザからは「Client Hello」の中にある「Server Name Indication extension」という部分にドメイン情報を入れてWEBサーバーに送っているようです(赤枠で囲ったところ)。暗号化はされていないのでWEBサーバー側でバーチャルホストの判断はできそうですね。。
※TLSのハンドシェイクについてはこちらの記事の前半にも書いているので見てみてください。