本文書の内容は次の一言に尽きます。Apache が設定ファイルを読み込むときに DNS を使用する必要がないようにして下さい。Apache が設定ファイルを読み込むときに DNS を使用する必要がある場合、信頼性の問題(起動しないかもしれません) やサービス拒否、盗用アタック(他のユーザからヒットを盗むことを含みます) の問題に直面するかもしれません。
<VirtualHost www.abc.dom> ServerAdmin webgirl@abc.dom DocumentRoot /www/abc </VirtualHost>
Apache が正常に機能するには、バーチャルホストごとに必ず二つの
情報が必要になります。それは、
ServerName
と、そのサーバが応答するための IP アドレス(最低一つ) です。
この例では IP アドレスを含んでいませんので、Apache は DNS
を使用して www.abc.dom
を見つけなければなりません。
設定ファイルを読み込んでいるときに何らかの理由で DNS
が利用できなかった場合、
バーチャルホストは設定されません。
そして、そのバーチャルホストに対するヒットには応答がなされません
(Apache 1.2 以前では起動すらしません)。
www.abc.dom
のアドレスが 10.0.0.1
だとします。では、次の設定について考えてみましょう。
<VirtualHost 10.0.0.1> ServerAdmin webgirl@abc.dom DocumentRoot /www/abc </VirtualHost>
現在 Apache は DNS 逆引きを使用してこのバーチャルホストの
ServerName
を見つけます。
その逆引きが失敗した場合は部分的にバーチャルホストを無効にします
(Apache 1.2 より前では起動すらしません)。
バーチャルホストが名前ベースであれば完全に無効になりますが、
IP ベースであれば概ね動作します。しかしながら、サーバ名を含む完全な
URL を生成しなければならない場合は、正しい URL の生成ができません。
次の例は上記の問題を解決しています。
<VirtualHost 10.0.0.1> ServerName www.abc.dom ServerAdmin webgirl@abc.dom DocumentRoot /www/abc </VirtualHost>
サービス拒否が起こる場合、(少なくとも) 二つのケースがあります。
Apache 1.2 より前を実行している場合、バーチャルホストのための
上記の二つの DNS 検索のうち一つでも失敗すれば起動すらしません。
またこの DNS 検索が自分の制御下にすらない場合もありえます。
例えば、abc.dom
が顧客のサーバの一つで、
DNS は顧客自身で管理している場合、顧客は単に
www.abc.dom
レコードを削除するだけで、
(1.2 より前の) サーバを起動不能にすることができます。
もう一つのケースは、より気付きにくいものです。 次の設定について考えてみましょう。
<VirtualHost www.abc.dom> ServerAdmin webgirl@abc.dom DocumentRoot /www/abc </VirtualHost>
<VirtualHost www.def.dom> ServerAdmin webguy@def.dom DocumentRoot /www/def </VirtualHost>
10.0.0.1 を www.abc.dom
に、10.0.0.2 を
www.def.dom
に割り当てているとします。また、
def.com
は顧客自身の DNS
の制御下にあるとします。この設定で、abc.com
に向けられたトラフィックすべてを奪うことができる位置に
def.com
を設置できています。後は単に
www.def.dom
が 10.0.0.1
を参照するように設定するだけです。DNS
は顧客側でコントロールされているので、www.def.com
レコードが好きな場所を指すように設定するのを止めることができません。
10.0.0.1 に対するリクエスト
(http://www.abc.dom/whatever
形式の URL
を入力したユーザからのものすべてを含みます)
は、def.dom
バーチャルホストで応答されます。
このようなことが何故起こるかもっとよく知るためには、
応答の必要なバーチャルホストへのリクエストに対して、
Apache がどのように整合性を確保するかについて、
深い議論が必要になります。おおまかな説明はこちらに記述されています。
Apache 1.1 で追加された
名前ベースのバーチャルホストのサポートにより、httpd
が動作しているホストの IP アドレスを、Apache
が知っている必要があります。このアドレスを得るために、
(もしあれば)グローバルの ServerName
や C の
gethostname
ファンクションコール
(これはコマンドプロンプトで "hostname"
と打ち込むのと同じ結果を返します。) を使用します。
それからこのアドレスの DNS 検索を行ないます。
現時点では、この検索の回避方法は何もありません。
DNS サーバのダウンが原因でこのルックアップが失敗するのを恐れる場合、
/etc/hosts
に hostname を挿入することができます。
(マシンが正常に起動できるように、これはおそらく既に存在します。)
それから、DNS が失敗したときに確実に /etc/hosts
を使用するように設定します。どんな OS を使っているかによりますが、
/etc/resolv.conf
や /etc/nsswitch.conf
を編集することによって完成できます。
もしサーバが他の理由により DNS を実行する必要が何もなければ、
Apache を HOSTRESORDER
環境変数を "local" に設定して
実行することで問題を避けることができるかもしれません。これは使用している
OS とリゾルバライブラリに依存します。
これは mod_env
を使って環境変数を制御していない限り、CGI にも影響します。
OS の man ページや FAQ を参照するようにしてください。
<VirtualHost>
中に IP アドレスを使うListen
中に IP アドレスを使うBindAddress
中に IP アドレスを使うServerName
を確実に与える
<VirtualHost _default_:*>
サーバを作成するDNS に関して、現状は全く宜しくありません。Apache 1.2 で、 DNS のイベントが失敗しても少なくとも起動プロセスが続くようにしましたが、 これが最高の解決方法ではないでしょう。アドレスの再割り当てが 必要不可避 となっている今日のインターネットにおいては、 設定ファイルの中で明示的な IP アドレスを要求する仕様は、 全く宜しくありません。
上で説明したサービス盗用攻撃に対して可能な対策は、 DNS の正引きにより返された IP アドレスから DNS の逆引きを実行し、 その二つの名前を比較することです。一致しない場合バーチャルホストは無効にされます。 これには、DNS の逆引きが適切に設定されている必要があります。(DNS の「二重の逆引き」は FTP サーバや TCP ラッパーにより一般的に使われているため、 ほとんどの管理者には馴染みのあるものでしょう)。
IP アドレスが使用されていなくて DNS が失敗した場合は、 どうしてもバーチャルホストウェブサーバを信頼性を確保して 起動させることは不可能のようです。設定の一部を無効にするというような 部分的な解決は、サーバの目的にもよりますが 起動しないよりも悪いかもしれません。
HTTP/1.1 が開発され、ブラウザやプロキシが Host
ヘッダを発行するようになったので、IP ベースのバーチャルホストを
全く使用しなくても済むようになるかもしれません。
この場合、ウェブサーバは設定中に DNS 参照をしなくても済みます。
しかし 1997 年 3 月時点の状況では、
商用レベルのウェブサーバで使用できるほどには、
これらの機能は広く開発が進んでいません。