1つのサーバに複数の仮想サーバ?仕事で使える魔法のLAMP(22)

Apacheは1つの物理的サーバに複数の仮想的なWebサーバを作ることを可能にする「バーチャルホスト」という機能を備えています。この機能の概要と、設定方法を解説します。(編集部)

» 2011年09月16日 00時00分 公開
[山口晴広株式会社イメージズ・アンド・ワーズ]

1つのWebサーバに複数の仮想的なサーバを構成

 前回からApache HTTP Server(以下Apache)の設定にとりかかっています。Apacheの設定ファイルを記述する前に覚えておきたい基本を解説しました。設定ファイルはテキストファイルですが、そこにはセクションコンテキストといった構造があります。

 コンテキストの一種に、バーチャルホストがあります。バーチャルホストというのは、1つのサーバの中に複数の仮想的なサーバを構成することを可能にする機能です。ここでいうサーバとは、OSやハードウェアのことではなく、ApacheならWebサーバということになります。つまり、Apacheサーバが1つあれば、複数のWebサーバを提供できるということです。

 今回はこのバーチャルホストの仕組みと設定方法について解説します。構築したいWebサーバが1つなら関係ない、と思われる読者もおられるかもしれませんが、筆者は仮に1つしか運用しないとしてもバーチャルホストとして設定します。後でバーチャルホストを追加するときも簡単に済みます。そして、Apacheにはデフォルトの仮想サーバが内部的に存在しているため、明示的にバーチャルホストを定義した方が分かりやすいと考えるからです。

またもやApache更新のお知らせ

 前々回、Apacheの脆弱性とその更新情報(バージョン2.2.20)をお伝えしましたが、またアップデートがありました。脆弱性対応によってプロトコル処理の部分に不具合を作ってしまったということで、短期間のうちにバージョン2.2.21が出ました。そのほかにも、いくつかの問題が修正されていますので、アップデートすることにします。

 ここからは2.2.21を前提に進めます。インストール先を変えるだけですが、configureスクリプトを次に示しますので、実行してください。以降、この状態でビルド、インストールしてあるものとして進めます。

./configure \
  --prefix=/opt/apache-httpd-2.2.21 \
  --enable-mods-shared=all \
  --enable-ssl \
  --with-pcre \
  --with-mpm=prefork \
  --with-berkeley-db \
  2>&1 | tee configure_log.txt

どうやってバーチャルホストを識別するか

 Apacheの内部にバーチャルホストが複数設定すると、Webブラウザからの接続があったとき、どのバーチャルホストに対する接続なのかを識別しなければなりません。識別方法として、最も単純かつ確実なのは、サーバのIPアドレスとポート番号の組み合わせによるものです。これをIPアドレスベースのバーチャルホストと呼びます。

 IPアドレスベースのバーチャルホストでは、HTTP(Hypertext Transfer Protocol)の標準である80番ポートだけを使いたいと考えると、IPアドレスをバーチャルホストの数だけ用意しなければなりません。IPアドレスは限りある資源ですから、この手法では大量のバーチャルホストを実現することが難しくなります。

 そこで、WebブラウザがWebサーバに接続するとき、HTTPのプロトコルヘッダにどのバーチャルホストにアクセスするかという情報を受け渡すことになりました。この方法なら、IPアドレスとポートが同一でも、別々のバーチャルホストを稼働させることができます。接続後、URL中のホスト名をWebブラウザがWebサーバに指定し、Webサーバはそれに基づいて応答します。これを名前ベースのバーチャルホストといいます。

 名前ベースのバーチャルホストはHTTPのバージョン1.1で導入された機能です。最初期のHTTP 1.0では、IPアドレスベースのバーチャルホストしか実現できませんでした。そのため、HTTP 1.1に対応していないブラウザでは、名前ベースのバーチャルホストには接続できません。といっても現在のブラウザで対応していないものはないので、この点は心配ありません。

 仮に、名前ベースのバーチャルホストに対して、名前を指定しないで接続しようとすると、Apacheの場合は最初に設定されたバーチャルホストが応答します。このように、ホスト名ではなくIPアドレスを指定したアクセスがやって来ることもあります。名前ベースのバーチャルホストを使うときは、最初に設定するのは中身が空の、無意味なものにしておいた方がよいでしょう。具体的な設定方法は後述します。

 IPアドレスを指定してのアクセスは、不便ですから実際には使いません。ただし、セキュリティの甘いサーバを探すために、存在するIPアドレスに対して順次アクセスを試みるクラッカーもいます。こういった行為をスキャンといいます。スキャン自体は不正とはいえないものの、スキャンによってクラッカーが設定ミスや甘い部分を発見し、攻撃のとっかかりを得てしまう可能性はあります。中身が空の、無意味なバーチャルホストを設定しておけば、スキャンをほかのバーチャルホストに寄せ付けないという効果があります。

 ほかに注意すべき点として、SSL(Secure Socket Layer)を使うときは、名前ベースのバーチャルホストを使えないWebブラウザがあるということが挙げられます。SSLではHTTPを暗号化していますが、接続相手のバーチャルホストが決まった後でないとSSLの復号ができません。つまり、プロトコルヘッダでホスト名を指定しても、データが暗号化されているので接続相手が分からないのです。

 この問題を解決するため、HTTPにホスト名の指定が導入されたように、SSLにも同じような仕組みが導入されています。Server Name Indication、略してSNIといいますが、これに対応しているWebサーバとWebブラウザであれば、SSLでも名前ベースのバーチャルホストを利用できます。

 Apacheはすでに対応しているのですが、問題はブラウザです。英語版のWikipediaを見るとどのWebブラウザが対応しているのかが分かります。大半のブラウザが対応しているものの、Windows XPのInternet Explorer(以下IE)は対応していません。SNIはIE7以降対応なのですが、XPではIE7、IE8ともに非対応ということです。

 つまり、相当数のユーザーがSNIを利用できないということになります。名前ベースのバーチャルホストがSSLで広く使われるようになるのはもう少し先になりそうです。

バーチャルホストを利用するには

 バーチャルホストは、前回解説したセクションとして設定します。次のように、IPアドレスとポート番号を指定してください。

<VirtualHost IPアドレス:ポート番号>
    バーチャルホストコンテキスト
</VirtualHost>

 このセクションの前に、待ち受けるIPアドレスとポート番号を設定する必要があります。仮に、IPアドレスを10.0.0.1、ポート番号を80としましょう。この場合、設定は次のようになります。

Listen 10.0.0.1:80
<VirtualHost 10.0.0.1:80>
    (略)
</VirtualHost>

 このセクション1つが、1つのバーチャルホストになります。さらに次のような設定を加えたとします。

Listen 10.0.0.1:80
<VirtualHost 10.0.0.1:80>
    (略)
</VirtualHost>
 
Listen 10.0.0.2:80
<VirtualHost 10.0.0.2:80>
    (略)
</VirtualHost>

 これで、IPアドレスベースのバーチャルホストを2つ設定できました。待ち受けるIPアドレスは「10.0.0.1」と「10.0.0.2」です。

 「VirtualHost」セクションで指定しているIPアドレスとポート番号に、同一のものを指定すれば名前ベースになります。名前ベースにしたい場合は、セクションの前にそのIPアドレスとポート番号を「NameVirtualHost」ディレクティブで指定しておく必要があります。さらに、サーバ名を指定する「ServerName」ディレクティブをセクション内に置きます。

Listen 10.0.0.1:80
NameVirtualHost 10.0.0.1:80
 
<VirtualHost 10.0.0.1:80>
    ServerName www.example.com
    (略)
</VirtualHost>
 
<VirtualHost 10.0.0.1:80>
    ServerName test.example.com
    (略)
</VirtualHost>

 これで「www.example.com」と「test.example.com」の2つのバーチャルホストを設定したことになります。この状態で、まったく異なるホスト名でのアクセスや、IPアドレス直接のアクセスがあると、そのアクセスは「www.example.com」のバーチャルホストが受けるようになります。そこで、前述のようにスキャンよけのため、ホスト名を指定しないバーチャルホストを定義します。

Listen 10.0.0.1:80
NameVirtualHost 10.0.0.1:80
 
<VirtualHost 10.0.0.1:80>
    ServerName 10.0.0.1
    (略。中身は空のWebサーバにする)
</VirtualHost>
 
<VirtualHost 10.0.0.1:80>
    ServerName www.example.com
    (略)
</VirtualHost>
 
<VirtualHost 10.0.0.1:80>
    ServerName test.example.com
    (略)
</VirtualHost>

 こうしておくと、少なくとも手当たり次第のスキャンは最初のバーチャルホストに行きます。「www.example.com」や「test.example.com」のIPアドレスが「10.0.0.1」であることが分からないと、本来のサーバへスキャンが届くことはありません。アドレスの逆引き設定を、「server1.example.com」など別のものにしておけば、より確実です。

 ただし、これはスキャンをよけるという気休め程度の防御でしかありません。サーバ名を知っている攻撃者からの攻撃もあり得るので、セキュリティ対策は別途考慮する必要があります。

 次回は、設定ファイルの詳細な構造や、ディレクトリ構造を解説します。

著者紹介

株式会社イメージズ・アンド・ワーズ
代表取締役
山口晴広(やまぐち はるひろ)



「仕事で使える魔法のLAMP」バックナンバー

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。