TLS拡張(RFC4366)仕様の一つ Server Name Indication(SNI)によって名前ベースのバーチャルホストでもSSLが使えますが、そもそもなぜ、名前ベースのバーチャルホストでSSLが使えないのかその理由と、SNIの仕組みと設定方法について調べてみました。
以前、WEBディレクターの方から、SSLを使っているサイトのバーチャルホストの設定依頼を受けて「SSL使ってるとバーチャルホストは使えないっすよ」とドヤ顔で答えてしまい、少し恥ずかしい思いをしました。(^^;)
昔の上司の言葉「常にアンテナを張っておけ!」を思い出します。
SNIの仕組み
SSLを使っていると当然ですがHTTPヘッダは暗号化されているので、クライアントがどのホスト名を指定しているのか判断できないため、先頭のバーチャルホスト(図の場合は lamp-sv)が表示されてしまいます。

SNIではSSL/TLSのやりとりの中で、暗号化していないホスト名をサーバに伝えてくれるので、指定したバーチャルホストを表示することができます。

SNIを使える条件
- Apache 2.2.12以降
- OpenSSL 0.9.8j以降
- ブラウザがSNIに対応
ApacheとOpenSSLは最近のサーバなら対応することができますが、ブラウザの対応状況には注意が必要です。
Apache ssl.conf の設定サンプル
SNIに未対応のブラウザ用に「SSLStrictSNIVHostCheck」デレクティブを off にするのがキモです。
▽ SSLStrictSNIVHostCheck Directive
http://httpd.apache.org/docs/2.2/mod/mod_ssl.html#sslstrictsnivhostcheck
LoadModule ssl_module modules/mod_ssl.so
Listen 443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
SSLPassPhraseDialog builtin
SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout 300
SSLMutex default
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
NameVirtualHost *:443
# offに設定(SNIに未対応のブラウザ用)
SSLStrictSNIVHostCheck off
<VirtualHost *:443>
ServerName lamp-sv
DocumentRoot "/var/www/lamp-sv"
<Directory "/var/www/lamp-sv">
Options FollowSymLinks
AllowOverride None
</Directory>
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
#「lamp-sv」用のサーバ秘密鍵と証明書
SSLCertificateFile /etc/pki/tls/certs/lamp-sv.crt
SSLCertificateKeyFile /etc/pki/tls/certs/lamp-sv.key
SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog
ErrorLog logs/lamp-sv_error_log
CustomLog logs/lamp-sv_access_log combined env=!nolog
</VirtualHost>
<VirtualHost *:443>
ServerName virtual-sv
DocumentRoot "/var/www/virtual-sv"
<Directory "/var/www/virtual-sv">
Options FollowSymLinks
AllowOverride None
</Directory>
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
#「virtual-sv」用のサーバ秘密鍵と証明書
SSLCertificateFile /etc/pki/tls/certs/virtual-sv.crt
SSLCertificateKeyFile /etc/pki/tls/certs/virtual-sv.key
SetEnvIf Request_URI "\.(gif|jpg|png|css|js)$" nolog
ErrorLog logs/virtual-sv_error_log
CustomLog logs/virtual-sv_access_log combined env=!nolog
</VirtualHost>
以上です。



コメント
[…] ■名前ベースのバーチャルホストでSSLを使う(SNI) | あぱーブログ SSLの必要性が高まると必然的にSNI使ってVirtualHostすることになるよなぁ […]
[…] 記事を発見。 https://blog.apar.jp/linux/378/ 試しに設定したところ、利用可能となりました。 […]