Apache でユーザごとの専用サブドメイン(ワイルドカードレコード)

JavaScript や Cookie のクロスドメイン制約によるセキュリティ対策とか、
ディレクトリ階層が少ないほうが良い?という噂の SEO 対策などの目的で、
ユーザごとにサブドメインを割り当てるサービスが増えてきました。
この BIGLOBE もそうですね。kawa.at.webry.info とユーザごとのドメイン。
bind+Apache で設定してみました。
 
※ここの「ユーザ」とは UNIX アカウントでなくて、ウェブサービスの会員のこと。
 

1. DNS を設定する

まず DNS (bind) 側は ワイルドカードレコード を利用します。
example.com.zone ファイルとかです。
*.example.com. IN A       192.168.xxx.yyy
foobar.example.com など、どのサブドメイン(ホスト名)を指定しても
実際には同じサーバ 192.168.xxx.yyy にアクセスするようになります。
*.example.com. 末尾の『.』をお忘れなく。
 

2. Apache を設定する

まず、mod_rewrite モジュールを利用可能にしてから(略)、
httpd.conf 等でバーチャルホストの設定を追加します。
<VirtualHost *:80>
ServerName      www.example.com
ServerAlias     *.example.com
DocumentRoot    /path/to/htdocs/www.example.com

(中略)
RewriteEngine   on

RewriteCond     /path/to/htdocs/%{HTTP_HOST}                    !-d
RewriteRule     ^ http://www.example.com/invalid.html  [R=permanent,L]

RewriteCond     /path/to/htdocs/%{HTTP_HOST}%{REQUEST_FILENAME} -f
RewriteRule     ^ /path/to/htdocs/%{HTTP_HOST}$1              [L]
</VirtualHost>
1つめの RewriteCond はディレクトリの存在確認、
2つめの RewriteCond はファイルの存在確認をしています。(後述)

3. 利用イメージ

今回は、ディレクトリの存在=サブドメインの有効性としています。
ユーザごとのサブドメインを実現するため、
/path/to/htdocs/ユーザ名.example.com
というユーザごとのディレクトリを作成して利用します。
 
http://kawanet.example.com/
⇒ kawanet ユーザ用ディレクトリ /path/to/htdocs/kawanet.example.com を参照
 
http://u-suke.example.com/
⇒ u-suke ユーザ用ディレクトリ /path/to/htdocs/u-suke.example.com を参照
 
もちろん、ユーザごとのディレクトリ内に存在するファイルは、
各ドメインで個別に利用できます。
 
http://kawanet.example.com/index.html
⇒ /path/to/htdocs/kawanet.example.com/index.html を返す
 
ユーザごとのディレクトリ内に存在しないファイルは、
全体共通で www.example.com 内のファイルが利用されます。
 
http://kawanet.example.com/foo/bar.html
⇒ /path/to/htdocs/kawanet.example.com/foo/bar.html が存在しない場合、
  /path/to/htdocs/www.example.com/foo/bar.html を返す
  (そちらにもなければ、通常通り 404 Not Found)
 
例えば、CSS や画像などの静的な共通ファイルについては、
各ユーザごとにコピーせずに、透過的に使えます。
ただし、キャッシュ効率を考えると、ドメイン名から指定して
www.example.com 内の共通ファイルを利用したほうが効率良さそう。
 
サブドメインが有効か否か(そのユーザが存在するか否か)を判断するには、
通常、アプリを組んで DB でユーザ存在確認するのが正攻法と思いますが、
今回は、ディレクトリが存在すればそのサブドメインは有効で、
ディレクトリが存在しなければ無効、という単純な仕組みにしてみました。
外部アプリを使わずに Apache のみで判別できるのがポイントです。
 
http://hoge.example.com/index.html
⇒ /path/to/htdocs/hoge.example.com/ が存在しない場合(=不正ドメイン)、
  http://www.example.com/invalid.html にリダイレクトします
 
これで、サブドメインたくさん並べたサービスも作れるようになったぞい。

この記事へのコメント

この記事へのトラックバック