Apache HTTP サーバ バージョン 2.4

この文書は、バーチャルホストの設定の際に よくある質問に答えるものです。想定している対象は 名前ベース や IP ベース のバーチャルホストを使って 一つのサーバで複数のウェブサイトを運用している状況です。

 一つの IP アドレスでいくつかの名前ベースの
    ウェブサイトを実行する
 一つの IP アドレスでいくつかの名前ベースの
    ウェブサイトを実行する 複数の IP アドレスのあるホストで名前ベースの
    ホスティングを行なう
 複数の IP アドレスのあるホストで名前ベースの
    ホスティングを行なう 違う IP アドレス (例えば、内部と外部アドレス)
    で同じコンテンツを送る
 違う IP アドレス (例えば、内部と外部アドレス)
    で同じコンテンツを送る 違うポートで違うサイトを運営する
 違うポートで違うサイトを運営する IP ベースのバーチャルホスティング
 IP ベースのバーチャルホスティング ポートベースと IP ベースの混ざった
    バーチャルホスト
 ポートベースと IP ベースの混ざった
    バーチャルホスト 名前ベースと IP ベースを混ぜた
    バーチャルホスト
 名前ベースと IP ベースを混ぜた
    バーチャルホスト 
 Virtual_host と
    mod_proxy を併用する 
 _default_ のバーチャルホストを
    使う 名前ベースのバーチャルホストから IP ベースの
    バーチャルホストに移行する
 名前ベースのバーチャルホストから IP ベースの
    バーチャルホストに移行する 
 ServerPath ディレクティブを
    使うサーバは IP アドレスを一つ割り当てられていて、DNS でマシンに
    複数の名前 (CNAME) が指定されています。このマシンで
    www.example.com と www.example.org
    のためのウェブサーバを実行させたいとします。
          Apache サーバの設定でバーチャルホストの設定をしただけで、
          知らない間にそのホスト名に対応する DNS のエントリが
          作成されたりはしません。そのサーバの IP アドレスに解決される
          ように DNS に名前を登録しなければなりません。
          そうでないと誰もあなたのウェブサイトを見ることはできません。
          ローカルでのテストのために hosts ファイルに
          エントリを追加することもできますが、この場合はその
          hosts エントリのあるマシンからしか動作しません。
    
    # Ensure that Apache listens on port 80
    Listen 80
    
    # Listen for virtual host requests on all IP addresses
    NameVirtualHost *:80
    
    <VirtualHost *:80>
    
      DocumentRoot /www/example1
      ServerName www.example.com
      
      # Other directives here
      
    
    </VirtualHost>
    
    <VirtualHost *:80>
    
      DocumentRoot /www/example2
      ServerName www.example.org
      
      # Other directives here
      
    
    </VirtualHost>
    
アスタリスクはすべてのアドレスにマッチしますので、主サーバは
    リクエストを扱いません。www.example.com は
    最初にあるため、優先順位は一番高くなり、default もしくは
    primary  のサーバと考えることができます。つまり、リクエストが
    どの ServerName ディレクティブにもマッチしない場合、
    一番最初の VirtualHost により扱われます。
* をシステムの実際の IP アドレスに置き換える
          こともできます。その場合は VirtualHost の引数は
          NameVirtualHost の引数と同じにしなければなりません
          :
            NameVirtualHost 172.20.30.40
            
            <VirtualHost 172.20.30.40>
             # etc ...
            
しかし、IP アドレスが予測不可能なシステム
          ――例えばプロバイダから動的に IP アドレスを取得して何らかの
          ダイナミック DNS を使っている場合など――においては、* 
          指定はさらに便利です。* はすべての IP アドレスに
          マッチしますので、この設定にしておけば IP アドレスが変更されても
          設定変更せずに動作します。
名前ベースのバーチャルホスティングではほぼすべての状況で、 上記の設定で希望の設定になっていることでしょう。 実際この設定が動作しないのは、IP アドレスやポートの違いによって 違うコンテンツを送るときだけです。
ここで説明されている方法は IP アドレスが 何個あっても同様にできます。
サーバには二つ IP アドレスがついています。一つ目
    (172.20.30.40) では主サーバ 
    server.domain.com を扱い、もう一方
    (172.20.30.50) では二つかそれ以上の数の
    バーチャルホストを扱います。
    
    Listen 80
    
    # This is the "main" server running on 172.20.30.40
    ServerName server.domain.com
    DocumentRoot /www/mainserver
    
    # This is the other address
    NameVirtualHost 172.20.30.50
    
    <VirtualHost 172.20.30.50>
    
        DocumentRoot /www/example1
        ServerName www.example.com
        
        # Other directives here ...
        
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.50>
    
        DocumentRoot /www/example2
        ServerName www.example.org
        
        # Other directives here ...
        
    
    </VirtualHost>
    
172.20.30.50 以外のアドレスへのリクエストは主サーバ
    が扱います。172.20.30.50 への、未知のホスト名または
    Host: ヘッダなしのリクエストは www.example.com
    が扱います。
サーバマシンは IP アドレスを二つ (192.168.1.1
    と 172.20.30.40) 持っています。このマシンは内部
    (イントラネット) と 外部 (インターネット) のネットワークの間に
    あります。server.example.com はネットワークの外からは
    外部アドレス (172.20.30.40) として解決されますが、
    ネットワークの中からは内部アドレス (192.168.1.1) 
    として解決されます。
VirtualHost 一つだけでサーバが内部のリクエストと
    外部のリクエストの両方に同じコンテンツで応答するようにできます。
    
    NameVirtualHost 192.168.1.1
    NameVirtualHost 172.20.30.40
    
    <VirtualHost 192.168.1.1 172.20.30.40>
    
        DocumentRoot /www/server1
        ServerName server.example.com
        ServerAlias server
    
    </VirtualHost>
    
これでどちらのネットワークからのリクエストも同じ VirtualHost
    で扱われるようになります。
内部ネットワークでは完全なホスト名の
          server.example.com の代わりに、単に server
          を使うことができます。
上の例では、IP アドレスのリストを、すべてのアドレスに
           同じコンテンツで応答する * に置き換えられます。
同じ IP に複数のドメインがあり、さらに複数のポートを使って リクエストを扱いたいときがあります。"NameVirtualHost" タグの中で ポートを定義することで、これを動作させられます。 NameVirtualHost name:port 無しや Listen ディレクティブで <VirtualHost name:port> を使おうとしても、その設定は動作しません。
    
    Listen 80
    Listen 8080
    
    NameVirtualHost 172.20.30.40:80
    NameVirtualHost 172.20.30.40:8080
    
    <VirtualHost 172.20.30.40:80>
    
        ServerName www.example.com
        DocumentRoot /www/domain-80
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40:8080>
    
        ServerName www.example.com
        DocumentRoot /www/domain-8080
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40:80>
    
        ServerName www.example.org
        DocumentRoot /www/otherdomain-80
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40:8080>
    
        ServerName www.example.org
        DocumentRoot /www/otherdomain-8080
    
    </VirtualHost>
    
サーバは www.example.com と www.example.org
    にそれぞれ解決される、二つの IP アドレス (172.20.30.40 と
    172.20.30.50) があります。
    
    Listen 80
    
    <VirtualHost 172.20.30.40>
    
        DocumentRoot /www/example1
        ServerName www.example.com
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.50>
    
        DocumentRoot /www/example2
        ServerName www.example.org
    
    </VirtualHost>
    
<VirtualHost> ディレクティブのどれでも
    指定されていないアドレス (例えば localhost) は、
    主サーバがあればそこに行きます。
サーバマシンはそれぞれ www.example.com と
    www.example.org にそれぞれ解決される、IP アドレスを二つ
    (172.20.30.40 と 172.20.30.50) 持っています。
    どちらもポート 80 と 8080 でホストを走らせます。
    
    Listen 172.20.30.40:80
    Listen 172.20.30.40:8080
    Listen 172.20.30.50:80
    Listen 172.20.30.50:8080
    
    <VirtualHost 172.20.30.40:80>
    
        DocumentRoot /www/example1-80
        ServerName www.example.com
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40:8080>
    
        DocumentRoot /www/example1-8080
        ServerName www.example.com
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.50:80>
    
        DocumentRoot /www/example2-80
        ServerName www.example.org
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.50:8080>
    
        DocumentRoot /www/example2-8080
        ServerName www.example.org
    
    </VirtualHost>
    
いくつかのマシンでは名前ベースの、その他では IP ベースのバーチャル ホストをします。
    
    Listen 80
    
    NameVirtualHost 172.20.30.40
    
    <VirtualHost 172.20.30.40>
    
        DocumentRoot /www/example1
        ServerName www.example.com
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40>
    
        DocumentRoot /www/example2
        ServerName www.example.org
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40>
    
        DocumentRoot /www/example3
        ServerName www.example3.net
    
    </VirtualHost>
    
    # IP-based
    <VirtualHost 172.20.30.50>
    
        DocumentRoot /www/example4
        ServerName www.example4.edu
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.60>
    
        DocumentRoot /www/example5
        ServerName www.example5.gov
    
    </VirtualHost>
    
Virtual_host と
    mod_proxy を併用する次の例は、フロント側のバーチャルホストで他のマシンへプロクシします。
    例では 192.168.111.2 のマシンではバーチャルホスト名は
    同じ名前で設定されています。複数のホスト名を一台のマシンにプロクシする
    場合は、ProxyPreserveHost On
    ディレクティブを使って、希望のホスト名を渡せるようになります。
    
    <VirtualHost *:*>
        ProxyPreserveHost On
        ProxyPass / http://192.168.111.2/
        ProxyPassReverse / http://192.168.111.2/
        ServerName hostname.example.com
    </VirtualHost>
    
_default_ のバーチャルホストを
    使う_default_ バーチャルホスト未指定の IP アドレスとポート、つまり他のバーチャルホストに 使われていないアドレスとポートの組み合わせ、へのすべてのリクエストを 受け取ります。
    
    <VirtualHost _default_:*>
    
        DocumentRoot /www/default
    
    </VirtualHost>
    
このようにワイルドカードのポートでデフォルトのバーチャルホストを 指定すると、主サーバにリクエストが行くのを防げます。
デフォルトのバーチャルホストは名前ベースのバーチャルホストに
    使われているアドレスとポートの組に送られたリクエストを扱うことは
    ありません。リクエストが不明な Host: ヘッダやその
    ヘッダがなかったりする場合は基本名前ベースバーチャルホスト (その
    アドレスとポートで設定ファイル中で最初のバーチャルホスト) により
    扱われます。
どんなリクエストでも AliasMatch
    や RewriteRule を使って
    単一の情報ページ (やスクリプト) に書き換えることができます。
_default_ バーチャルホスト一つめの設定とほぼ同じですが、サーバは複数のポートを listen しており、
    80 番ポートに対して二つめの _default_ バーチャルホストを
    設定したい場合です。
    
    <VirtualHost _default_:80>
    
        DocumentRoot /www/default80
        # ...
    
    </VirtualHost>
    
    <VirtualHost _default_:*>
    
        DocumentRoot /www/default
        # ...
    
    </VirtualHost>
    
80 番ポートのデフォルトバーチャルホスト (ワイルドカードポートの デフォルトバーチャルホストよりも前に書かれていなければなりません) は 未指定の IP アドレスに送られたすべてのリクエストを扱います。 主サーバはリクエストを扱いません。
_default_ バーチャルホスト80 番ポートにはデフォルトのバーチャルホストが必要で、他の バーチャルホストはデフォルトが必要ない場合です。
    
    <VirtualHost _default_:80>
    DocumentRoot /www/default
    ...
    </VirtualHost>
    
80 番ポートへのアドレス未指定のリクエストはデフォルトのバーチャル ホストから送られます。他の未指定のアドレスとポートへのリクエストは 主サーバから送られます。
ホスト名が名前 www.example.org のバーチャルホスト
    (名前ベースの例の 2 番目の設定) が専用の IP アドレスを
    得たとします。名前ベースのバーチャルホストの古い IP アドレスを
    キャッシュしているネームサーバやプロキシのために移行期間中は両方の
    バーチャルホストを提供したいとします。
答は簡単です。単に新しい IP アドレス (172.20.30.50)
    を VirtualHost ディレクティブに追加することで
    できます。
    
    Listen 80
    ServerName www.example.com
    DocumentRoot /www/example1
    
    NameVirtualHost 172.20.30.40
    
    <VirtualHost 172.20.30.40 172.20.30.50>
    
        DocumentRoot /www/example2
        ServerName www.example.org
        # ...
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40>
    
        DocumentRoot /www/example3
        ServerName www.example.net
        ServerAlias *.example.net
        # ...
    
    </VirtualHost>
    
このバーチャルホストは新しいアドレス (IP ベースのバーチャルホストとして) と古いアドレス(名前ベースのバーチャルホストとして) の両方から アクセスできます。
ServerPath ディレクティブを
    使う名前ベースのバーチャルホストが二つあるサーバがあるとします。
    正しいバーチャルホストを得るためにはクライアントは正しい
    Host: ヘッダを送らなければなりません。
    古い HTTP/1.0 はそのようなヘッダを送らないので、Apache はクライアントが
    どのバーチャルホストを意図したのかさっぱりわかりません
    (なので、主バーチャルホストでリクエストを扱います)。
    可能な限りの下位互換性を得るため、名前ベースのバーチャルホストの
    URL 接頭辞へのリンクの書かれたページを返す、
    主バーチャルホストが作成されます。
    
    NameVirtualHost 172.20.30.40
    
    <VirtualHost 172.20.30.40>
    
        # primary vhost
        DocumentRoot /www/subdomain
        RewriteEngine On
        RewriteRule ^/.* /www/subdomain/index.html
        # ...
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40>
    DocumentRoot /www/subdomain/sub1
    
        ServerName www.sub1.domain.tld
        ServerPath /sub1/
        RewriteEngine On
        RewriteRule ^(/sub1/.*) /www/subdomain$1
        # ...
    
    </VirtualHost>
    
    <VirtualHost 172.20.30.40>
    
        DocumentRoot /www/subdomain/sub2
        ServerName www.sub2.domain.tld
        ServerPath /sub2/
        RewriteEngine On
        RewriteRule ^(/sub2/.*) /www/subdomain$1
        # ...
    
    </VirtualHost>
    
ServerPath ディレクティブの設定に
    より、URL http://www.sub1.domain.tld/sub1/ は
    常に sub1-vhost により扱われます。URL
    http://www.sub1.domain.tld/ へのリクエストは
    クライアントが正しい Host: ヘッダを送ったときにのみ
    sub1-vhost から送られます。Host: ヘッダがなければ
    クライアントは主ホストの情報ページを得ます。
一つ奇妙な動作をする点があることは覚えておいてください。
    http://www.sub2.domain.tld/sub1/ へのリクエストも
    Host: ヘッダがなければ sub1-vhost により扱われます。
正しい Host: ヘッダを送ったクライアントはどちらの
    URL、つまり接頭辞がある方も無い方も使えるように
    RewriteRule ディレクティブが
    使われています。