Dabits

サーバサイドから運営まで何でもやるエンジニア系DJ

ユーザ毎にバーチャルホストを設定する方法

//概要 普段、ユーザのpublic_htmlディレクトリはhttp://www.example.com/~foo/の形で公開される。 今回は、それをワンランクアップし、http://foo.example.com/でアクセスできるように設定する。


//mod_vhost_aliasを使用した方法Apache付属のモジュールの中に、mod_vhost_aliasと言うモジュールがある。  これを使用すると、たった一行でバーチャルドメインが実現できる。以下に例を示す。

VirtualDocumentRoot /home/%1/public_html http://foo.example.com/に対して/home/foo/public_htmlを割り当てる。

お分かりいただけるだろうか。見ての通り実に簡単である。 ただし問題点はある。それは各種ラッパーを一切使用できないことだ。 理由は、ラッパーの仕組みを思い出せば分かってくる。 数あるラッパー、例を挙げるとCGIWrapの場合ユーザとパスを判別するには環境変数の'PATH_INFO'か'QUERY_STRING'から情報を抜き取って判別している。 PATH_INFOの場合、/~foo/hoge.cgiの形式でないと認識できないし、 QUERY_STRINGの場合、/path-to-cgiwrap/cgiwrap/foo/hoge.cgiの形式でないと認識できない。 つまり、バーチャルホストにした際のパスでは/~foo/hoge.cgiにならないため認識できないのである。 対処方法としては、以下のようにmod_rewriteを使用した方法がある。


//mod_rewriteを使用した方法 1,/~fooへマッピングする ・すぐに思いつく方法としては、http://foo.example.com/へ向けられた要求を/~fooへ向けることである。 これにより、バーチャルホストのマッピングができるうえに、CGIWrapの認識できるパス通りにPATH_INFOを設定できる。 以下に例を示す。

ServerName www.example.com ServerAlias *.example.com RewriteEngine On RewriteCond %{HTTP_HOST} !^www\.example\.com$ RewriteCond %{REQUEST_URI} !^/cgiwrap/ RewriteCond %{REQUEST_URI} !^/icons/ RewriteCond %{REQUEST_URI} !^/~ ↑www.example.com , /cgiwrap , /icons , /~ を含むアドレスにはマッピングしない RewriteRule ^(.+) %{HTTP_HOST}$1 [C] RewriteRule ^([^.]+)\.example\.com/(.*) /~$1/$2 [PT] RewriteRule ^([^.]+)\.example\.com$ /~$1/ [PT] http://foo.example.com/に対して/~fooを割り当てる。

これで、/~fooに対してマッピングできる。しかし、これにも欠点がある。 それは、cgiなどで相対パス等を取り扱ったときにhttp://foo.example.com/~foo/と表示されてしまう点だ。 NotFoundなどのエラーメッセージにも同様の症状が発生する。http://foo.example.com/hoge.cgiでアクセスしたはずなのに、 いつの間にかhttp://foo.example.com/~foo/hoge.cgiになっていた、なんていうことも起こってしまう。 これは当然の挙動としか言いようが無い。http://foo.example.com/に対して http://foo.example.com/~foo/マッピングしているのだから。 対処法としては、以下の方法がある。 2,/home/foo/public_htmlへマッピングし、CGIScriptに対しては/cgi-bin/cgiwrap/foo/へマッピングする ・標準時は/home/foo/public_htmlへ直接マッピングをかけてあげて、 ラッパー対象ファイルに対しては/cgi-bin/cgiwrap/foo/へマッピングすれば、CGIWrapがQUERY_STRINGを使用して 認識できるので見事に実現できるはずである。以下に例を示す。

ServerName www.example.com ServerAlias *.example.com RewriteEngine On RewriteCond %{HTTP_HOST} !^www\.example\.com$ RewriteCond %{REQUEST_URI} !^/cgiwrap/ RewriteCond %{REQUEST_URI} !^/icons/ RewriteCond %{REQUEST_URI} !^/~ ↑www.example.com , /cgiwrap , /icons , /~ を含むアドレスにはマッピングしない RewriteRule ^(.+) %{HTTP_HOST}$1 [C] # For CGI Files RewriteRule ^([^.]+)\.example\.com/(.+)\.cgi(.*) /cgi-bin/cgiwrap/$1/$2\.cgi$3 [NS,T=application/x-http-cgi,PT,L] http://foo.example.com/hoge.cgiに対して/cgi-bin/cgiwrap/foo/hoge.cgiを割り当てる。 # For Normal Files RewriteRule ^([^.]+)\.example\.com/(.*) /home/$1/public_html/$2 [L] RewriteRule ^([^.]+)\.example\.com$ /home/$1/public_html [L] http://foo.example.com/に対して/home/foo/public_htmlを割り当てる。

これで、ユーザ毎にバーチャルドキュメントを実現でき、かつCGIWrapが有効になる。