Apache HTTP サーバ バージョン 2.4

Apache > HTTP サーバ > ドキュメンテーション > バージョン 2.4 > バーチャルホスト

# バーチャルホストの例

この日本語訳はすでに古くなっている 可能性があります。 最近更新された内容を見るには英語版をご覧下さい。

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

## 一つの IP アドレスでいくつかの名前ベースの ウェブサイトを実行する

サーバは 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 アドレスが 何個あっても同様にできます。

サーバには二つ 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 アドレス (例えば、内部と外部アドレス) で同じコンテンツを送る

サーバマシンは 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>`

## IP ベースのバーチャルホスティング

サーバは `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`) は、 主サーバがあればそこに行きます。

## ポートベースと IP ベースの混ざった バーチャルホスト

サーバマシンはそれぞれ `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 ベースを混ぜた バーチャルホスト

いくつかのマシンでは名前ベースの、その他では 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 番ポートへのアドレス未指定のリクエストはデフォルトのバーチャル ホストから送られます。他の未指定のアドレスとポートへのリクエストは 主サーバから送られます。

## 名前ベースのバーチャルホストから IP ベースの バーチャルホストに移行する

ホスト名が名前 `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` ディレクティブが 使われています。