apacheでvirtualhostが上手く動かない時の設定確認項目

apacheで名前ベースのvirtualhost環境を構築したものの、なぜか上手く動かない時の確認項目を紹介します。シンプルな設定だけにどこでハマっているかの気づきになれば幸いです。

問題点1:複数のvirtualhostを設定しているのに、1つ目のバーチャルホスト(サイト)が必ず表示される

まずは、構築したい環境を説明します。

1台のWebサーバ(apache)で複数のドメインの名前ベースのバーチャルホストを設定します。具体的には、

  • 一つ目のWebサイトは、https://dassyi.com
    • ドキュメントルートは、/home/user001/public_html
    • アクセスログは/var/log/httpd/access_log、/var/log/httpd/error_log に記録
  • 二つ目のWebサイトは、http://medaka.dassyi.com
    • ドキュメントルートは、/home/user002/public_html
    • アクセスログは/home/user002/log/access_log、/home/user002/log/error_log に記録

という構成でコンフィグを作成します。

1つ目のwebサイトは、/etc/httpd/conf.d/dassyi.confとして、以下のように作成します。

# HTTPでアクセスがあった場合は、HTTPSへ強制リダイレクト
<VirtualHost *:80>
 ServerName dassyi.com
 RewriteEngine On
 RewriteCond %{HTTPS} off
 RewriteRule ^(.*)$ https://dassyi.com$1 [R=301,L]
</VirtualHost>


<VirtualHost *:443>
ServerName dassyi.com:443
DocumentRoot /home/user001/public_html

<Directory "/home/user001/public_html">
 AllowOverride AuthConfig FileInfo Indexes Limit
 Require all granted
 Options +FollowSymLinks -Indexes
</Directory>

ErrorLog /var/log/httpd/error_log
TransferLog /var/log/httpd/access_log
LogLevel warn

SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

SSLHonorCipherOrder on

SSLCipherSuite PROFILE=SYSTEM
SSLProxyCipherSuite PROFILE=SYSTEM

SSLCertificateFile /etc/pki/tls/certs/dassyi.com.crt
SSLCertificateKeyFile /etc/pki/tls/private/dassyi.com.key

</VirtualHost>

となります。2つ目のサイトは、/etc/httpd/conf.d/medaka.confとして、以下のように作成します。設定内容はドメインやディレクトリ以外はほぼ同じです。

# HTTPでアクセスがあった場合は、HTTPSへ強制リダイレクト
<VirtualHost *:80>
 ServerName medaka.dassyi.com
 RewriteEngine On
 RewriteCond %{HTTPS} off
 RewriteRule ^(.*)$ https://medaka.dassyi.com$1 [R=301,L]
</VirtualHost>


<VirtualHost *:443>
ServerName medaka.dassyi.com:443
DocumentRoot /home/user002/public_html

<Directory "/home/user002/public_html">
 AllowOverride AuthConfig FileInfo Indexes Limit
 Require all granted
 Options +FollowSymLinks -Indexes
</Directory>

ErrorLog /home/user002/log/error_log
TransferLog /home/user002/log/access_log
LogLevel warn

SSLEngine on
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

SSLHonorCipherOrder on

SSLCipherSuite PROFILE=SYSTEM
SSLProxyCipherSuite PROFILE=SYSTEM

SSLCertificateFile /etc/pki/tls/certs/medaka.dassyi.com.crt
SSLCertificateKeyFile /etc/pki/tls/private/medaka.dassyi.com.key

</VirtualHost>

いざ設定を実施して、アクセスしてみると、https://dassyi.com でも、https://medaka.dassyi.comでも、dassyi.comのページが表示されてしまう現象が発生しました。

解決方法1:コンフィグのServerNameのドメインが誤っていた

結論から先に述べますと、medaka.confの中のServerNameのドメインが、「dassy」となっており、最後の「i」が抜け落ちており、全く別のドメインとして設定されていました。

この場合、https://medaka.dassyi.comでアクセスしても、このサーバの設定上は存在しないバーチャルドメインなので、一番最初に読み込まれたdassyi.confがデフォルトとして扱われており、こちらのhttps://dassyi.comの内容が表示されていました。

ちょっとした凡ミスですが、なかなか気が付かず時間を無駄にしましたので、参考になれば幸いです。

問題点2:存在しない(未定義の)Virtualhostにアクセスしない設定を追加したが、うまく有効にならない

次に、そもそも設定していないバーチャルホストにアクセスがあっても、デフォルトとして読み込まれているバーチャルホストが表示されるのはどうかと思いました。(問題点1の場合ですと、存在しないバーチャルにアクセスすると、https://dassyi.comが表示されてしまう。もちろんDNS的に名前解決が出来る前提です)

そこで、以下のようなコンフィグファイルを準備して、存在しない(未定義の)Virtualhostにアクセスしない設定を追加しました。このときのファイル名は、virtual-00.conf としました。

<VirtualHost _default_:80>
    ServerName any
    <Location />
        Require all denied
    </Location>
</VirtualHost>

<VirtualHost _default_:443>
  ServerName any
  SSLEngine on
  SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
  SSLHonorCipherOrder on
  SSLCipherSuite PROFILE=SYSTEM
  SSLProxyCipherSuite PROFILE=SYSTEM
  SSLCertificateFile /etc/pki/tls/certs/dassyi.com.crt
  SSLCertificateKeyFile /etc/pki/tls/private/dassyi.com.key

 <Location />
  Require all denied
 </Location>
</VirtualHost>

しかしながら、存在しないバーチャルホストにアクセスしても、やはりhttps://dassyi.comが表示されてしまい、うまく設定が反映されませんでした。

解決方法2:コンフィグファイルには読み込まれる順番がある

こちらの問題点は、コンフィグファイルの名前でした。apacheの/etc/httpd/conf.d/にあるコンフィグファイルには読み込まれる順番があり、私の場合、dassyi.conf → medaka.conf → virtual-00.confというように、アルファベット順で読み込まれます。(その他デフォルトで存在するconfファイルはここでは割愛しています)

そのため、デフォルトにしたかった、virtual-00.confが最後の読み込まれていたため、有効になっておりませんでした。対応方法としましては、ファイル名を 00-virtual.conf とすることで、希望の動作となることを確認しております。

皆さんもコンフィグファイルの読み込み順番があることを知っておいてください。

なお、補足になりますが、HTTPの時代は、今回のような存在しない(未定義の)Virtualhostにアクセスしない設定は有効でしたが、HTTPSが主流となっている現在ではあまり有効ではありません。なぜなら、アクセス時にブラウザがサーバ証明書のエラーを表示するからです。とはいえ、ワイルドカード証明書を使用した場合など全くないという訳ではないので、ここで紹介しておきます。

問題点3:公式サイトのコンフィグの設定例をコピー

apache公式サイトに、以下のような記述例があります。(DocumentRootの場所は変えています)

NameVirtualHost *:80

<VirtualHost *:80>
ServerName www.domain.tld
ServerAlias domain.tld *.domain.tld
DocumentRoot /home/user001/public_html
</VirtualHost>

<VirtualHost *:80>
ServerName www.otherdomain.tld
DocumentRoot /home/user002/public_html
</VirtualHost>

問題点1でハマっていた時に、うまく動かず、どの設定が正しいのかわからなくなり、公式サイトの設定ををそのままコピペして動かすけれど、やはり動きませんでした。

解決方法3:エラーログを確認し、コンフィグの内容に誤りを見つける

この時は、エラーログファイルに、

[authz_core:error] [pid 23511:tid 140637898798848] [client 192.168.1.101:52169] AH01630:
client denied by server configuration: /home/user001/public_html

といった内容が記録されておりました。こちら確認すると、アクセス権がないとのことで、<Directory “/home/user001/public_html”> タグで、「Require all granted」がない事によるエラーとなっておりました。こちらは、ディレクトリへのアクセスをすべて許可するという設定になり、この記載がないと、当然アクセスが出来ないので、サイトの表示もされません。

このように公式サイトの例もそのままコピペではうまく動かないこともあるので、当方のdassyi.confやmedaka.confの内容をコピーするようにしてください。また、うまく動作しない時は、エラーログを必ず確認するようにしてください。何かヒントになる情報が記録されています。

今回はここまでです。最後までお読みいただきありがとうございました。