Apache には NameVirtualHost という、HTTP Header の Hostの値によって、 返すコンテンツを変えることができる機能があります。
使い方は例えば
<VirtualHost *:80> ServerName test1.localhost:80 DocumentRoot /var/www/test1/ </VirtualHost> <VirtualHost *:80> ServerName test2.localhost:80 DocumentRoot /var/www/test2/ </VirtualHost>
こんな風に。
HTTPS対応したいときは
<VirtualHost *:443> ServerName test1.localhost:443 SSLCertificateFile /etc/httpd/conf/server1.crt SSLCertificateKeyFile /etc/httpd/conf/server1.key DocumentRoot /var/www/test1/ </VirtualHost> <VirtualHost *:443> ServerName test2.localhost:443 SSLCertificateFile /etc/httpd/conf/server2.crt SSLCertificateKeyFile /etc/httpd/conf/server2.key DocumentRoot /var/www/test2/ </VirtualHost>
こう。
コンテンツを試しに
cat /var/www/test1/index.html test1 cat /var/www/test2/index.html test2
おいてみます。
早速curl と opensslでアクセスしてみましょう。
> curl http://127.0.0.1/ test1 > curl http://127.0.0.1/ -H"Host: test1.localhost" test1 > curl http://127.0.0.1/ -H"Host: test2.localhost" test2
> curl http://test1.localhost/ test1 > curl http://test1.localhost/ -H"Host: test1.localhost" test1 > curl http://test1.localhost/ -H"Host: test2.localhost" test2
> curl http://test2.localhost/ test2 > curl http://test2.localhost/ -H"Host: test1.localhost" test1 > curl http://test2.localhost/ -H"Host: test2.localhost" test2
- Host に応じてコンテンツが返ってきます。
- Host が一致しないと、最初に見つかったVirtualHostのコンテンツが返ってきます。
注 curl はHostヘッダを追加しないと、URLのホスト名をHostヘッダに入れます。
> openssl s_client -connect test1.localhost:443 <test1のCertification> GET / HTTP/1.1 HTTP/1.1 400 Bad Request > openssl s_client -connect test2.localhost:443 <test1のCertification> GET / HTTP/1.1 HTTP/1.1 400 Bad Request
> openssl s_client -connect 127.0.0.1:443 <test1のCertification> GET / HTTP/1.1 HTTP/1.1 400 Bad Request > openssl s_client -connect 127.0.0.1:443 <test1のCertification> GET / HTTP/1.1 Host: test1.localhost HTTP/1.1 200 OK test1 > openssl s_client -connect 127.0.0.1:443 <test1のCertification> GET / HTTP/1.1 Host: test2.localhost HTTP/1.1 200 OK test2
> openssl s_client -connect 127.0.0.1:443 -servername test1.localhost <test1のCertification> GET / HTTP/1.1 HTTP/1.1 400 Bad Request > openssl s_client -connect 127.0.0.1:443 -servername test1.localhost <test1のCertification> GET / HTTP/1.1 Host: test1.localhost HTTP/1.1 200 OK test1 > openssl s_client -connect 127.0.0.1:443 -servername test1.localhost <test1のCertification> GET / HTTP/1.1 Host: test2.localhost HTTP/1.1 400 Bad Request
> openssl s_client -connect 127.0.0.1:443 -servername test2.localhost <test2のCertification> GET / HTTP/1.1 HTTP/1.1 400 Bad Request > openssl s_client -connect 127.0.0.1:443 -servername test2.localhost <test2のCertification> GET / HTTP/1.1 Host: test1.localhost HTTP/1.1 400 Bad Request > openssl s_client -connect 127.0.0.1:443 -servername test2.localhost <test2のCertification> GET / HTTP/1.1 Host: test2.localhost HTTP/1.1 200 OK test2
- servername を与えないと、最初に見つかったtset1.localhostの証明書を渡されますが、 Host ヘッダに応じて、帰ってくるコンテンツが変わります。
- servername を与えると、Hostヘッダが一致しないとBad Requestが返ってきます。
- そもそもHostヘッダがないとBad Requestが帰ってきます。
注 openssl はconnect でホスト名を指定しても servernameには使いません。