Apache のネームベースのバーチャルホスト

### Apache HTTP Server Version 1.3

# Apache のネームベースのバーチャルホストのサポート

参考: IP ベースのバーチャルホストのサポート

## ネームベースと IP ベースのバーチャルホストの比較

初期のバージョンの HTTP では (他の多くのプロトコル、例えば FTP と同様) 一つのサーバ上でのバーチャルホストごとに異なった IP アドレスが必要でした。 いくつかのプラットフォームでは、 これが実行可能なバーチャルホストの数を限定してしまうことになりました。 また、IP アドレスの数には限りがあるということについての懸念から、 レジストラ (ARIN, RIPE, APNIC) はバーチャルホストごとに IP を割り当てるようなことは避けるよう強く要請しています。

`HTTP/1.1` プロトコルや、 `HTTP/1.0` での一般的な拡張には、 どの名前でリクエストされているのかをサーバが判別する方法があります。 Apache 1.1 以降では昔からの「ホスト名ごとに IP アドレス」という方法に加えて、 このアプローチもサポートしています。

ネームベースのバーチャルホストの利点としては、 事実上無限の数のサーバを運用できるということ、設定し利用するのが簡単なこと、 追加のハードウェアやソフトウェアが不要なこと、というのがあります。 もっとも大きな問題点としては、 クライアントはこのプロトコルをサポートしなければいけないということです。 ほとんどすべてのブラウザでサポートされていますが、 サポートしていないブラウザも少ないながらも依然として存在しています。 そのために問題が発生することがあります。これに対する解決方法に なり得るものは後述します。

## ネームベースのバーチャルホストを利用する

ネームベースのバーチャルホストを利用するのはとても簡単です。 見た目には従来の IP ベースの方法に似ています。 IP ベースとネームベースのバーチャルホストの設定の重要な違いは、 `NameVirtualHost` ディレクティブで、ネームベースのバーチャルホストのターゲットとして使われる IP アドレスを指定するということです。

たとえば、 `www.domain.tld` と `www.otherdomain.tld` の両方が `111.22.33.44` という IP アドレスを指しているとしましょう。 そのような場合は、Apache の設定ファイルの一つ (通常は `httpd.conf` か `srm.conf` のどちらか) に 以下のようなコードを追加するだけです:

        NameVirtualHost 111.22.33.44

        <VirtualHost 111.22.33.44>
        ServerName www.domain.tld
        DocumentRoot /www/domain
        </VirtualHost>

        <VirtualHost 111.22.33.44>
        ServerName www.otherdomain.tld
        DocumentRoot /www/otherdomain
        </VirtualHost>

もちろん、ディレクティブを `<VirtualHost>` セクションに追加することができます (するべきです) 。 これを動作するために必要なことは、 `www.domain.tld` や `www.otherdomain.tld` という名前が IP アドレス `111.22.33.44` を指しているか確認するということだけです。

注意: `NameVirtualHost` ディレクティブで IP アドレスを指定した場合、その IP アドレスへのリクエストは、 常にそのリクエストにマッチする <VirtualHost> でのみ処理されます。 その IP アドレスでは「メインサーバ」は決して見えません。 バーチャルホストを使うのであれば「メインサーバ」を独立したサーバとして使うのは 止めるべきです。むしろ、その部分はすべてのバーチャルホストで共通な設定ディレ クティブを記述するために使用してください。 言い換えると、サーバ上で運用したいすべてのサーバ (ホスト名) について <VirtualHost> セクションを追加すべきです。

Apache 1.3.13 以降では、 `NameVirtualHost` の IP アドレスにワイルドカード `*` を指定できます。このワイルドカードは、 より具体的なバーチャルホストのディレクティブでカバーされていない任意の IP アドレスにマッチします。 これは、前もって IP アドレスを知ることのできないサーバを設定する際に役 に立ちます。たとえば、動的に IP アドレスが設定される場合や、同じ設定ファ イルを共有する負荷分散のためのクラスタの一部となる場合などです。

さらに、複数の名前でサーバアクセスができるようにしたいことも多いでしょう。 たとえば、同じ IP アドレスを指す `domain.tld` と `www2.domain.tld` のどちらででもサーバにアクセスできるようにしたい場合などです。 それどころか、`domain.tld` のどんなアドレスででもそのサーバに アクセスできるようにしたい場合があるかもしれません。 このようなことは、 `ServerAlias` ディレクティブを <VirtualHost> セクションに記述することで実現できます。 たとえば:

        ServerAlias domain.tld *.domain.tld

`*` や `?` をワイルドカード文字として使用できることに 注意してください。

普通はドメイン名を省略するであろうローカルのユーザのために `ServerAlias` が必要かもしれません。 たとえば、もしローカルのユーザが "www" や "www.foobar" とタイプするのに 親しんでいる場合、 `ServerAlias www www.foobar` を追加する必要があるでしょう。 クライアントが名前の解決にどのようなドメイン名を使ったのかをサーバが 知ることは不可能です。クライアントはリクエストにそのような情報を含めない からです。 通常は、`ServerAlias` ディレクティブは同じバーチャルホストに対して 異なったホスト名を割り当てる方法です。

## 古いブラウザとの互換性

上で書いたように、ネームベースのバーチャルホストが正しく動作する ために必要な情報を送ってこないクライアントが依然として存在しています。 そのようなクライアントに対しては、該当する IP アドレスについて、 一番最初に設定されているバーチャルホスト (プライマリのネームベースのバーチャルホスト) からページが送り返されます。

`ServerPath` ディレクティブで対処が可能です。ちょっと不格好ですけれども。

設定例:

        NameVirtualHost 111.22.33.44

        <VirtualHost 111.22.33.44>
        ServerName www.domain.tld
        ServerPath /domain
        DocumentRoot /web/domain
        </VirtualHost>

この例にはどういう意味があるでしょうか? これは "`/domain`" で始まる URI へのリクエストはすべて、 バーチャルホスト `www.domain.tld` で処理される、という意味です。 つまり、すべてのクライアントで `http://www.domain.tld/domain/` でアクセスできるページが、 `Host:` ヘッダを送ってくるクライアントであれば `http://www.domain.tld/` としてもアクセスできる、という 意味です。

これを実用的なものとするためには、 プライマリのバーチャルホストのページに `http://www.domain.tld/domain/` へのリンクを設置します。 そして、バーチャルホストのページでは、 純粋な相対リンク (例: "`file.html`" や "`../icons/image.gif`")、 あるいは `/domain/` で始まるリンク (例: "`http://www.domain.tld/domain/misc/file.html`" や "`/domain/misc/file.html`") だけを設置します。

これには、幾分かの規律が必要となりますが、 このようなガイドラインを忠実に守ることにより、たいていの場合、 すべてのブラウザで―新しいブラウザでも古いものでも― 作成したページが見えるということを保証します。

参考: ServerPath 設定例

### Apache HTTP Server Version 1.3