それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

ワイルドカードでApacheのVirtualHost-はてなブログでやってるあれ

ワイルドカードApacheのバーチャルホストを使いたい。

ワイルドカードApacheの設定するとどうなるか。はてなブログでやってるあれですね。

ワイルドカードドメインディレクトリを一致させる。

takuya-1st.example.com  #=> /var/www/example.com/takuya-1st/
takuya-2nd.example.com #=> /var/www/example.com/takuya-2nd/
takuya-3rd.example.com #=> /var/www/example.com/takuya-3rd/
takuya-4th.example.com #=> /var/www/example.com/takuya-4th/
takuya-5th.example.com #=> /var/www/example.com/takuya-5th/

などと、ドメイン名をワイルドカードでアクセスできるようにしたいと思います。

たとえばホスティングで使われます。

takuya.example.com   #=> /home/takuya/public_html
hoshi.example.com     #=> /home/hoshi/public_html
akemi.example.com    #=> /home/akemi/public_html
ohmori.example.com  #=> /home/ohmori/public_html
ryohei.example.com   #=> /home/ryohei/public_html


などの"ユーザー名.ドメイン"がつかえて、
"USERNAME.example.com" でアクセスできるようなります。

まぁ、はてなブログでやってるのは、ワイルドカードドメインとリバプロ構成でユーザー名をフレームワークに渡してるんでしょうけど。Apacheで幾つものサイト持つにはとっても便利です。

ディレクトリとユーザー名のマッピング

ディレクトリとユーザー名をマッピング出来たら最高です

takuya.example.com #-------> /home/takuya/public_html

これをすれば、ほんとうにゼロ設定のテスト・本番環境の出来上がりですよね。ディレクトリ作ったら、そのディレクトリ名がホスト名になりますから。

ディレクトリの有無=>ドメイン名のアクセス成否

になって、サーバー・ドメイン管理が恐ろしく簡単になります。

やりかた。

mod_vhost_alias を使います。

むかしは mod_rewrite を活用しました、活用例もたくさんググったら出てきます。しかし、そんな面倒なことをしなくてもすっごく簡単になっています。ワイルドカード、ServerAliasとVirtualDocumentRoot。たったこれだけです。
いまでも mod_rewrite を活用した方がいい場面もあります。(後述

  1. ワイルドカードドメインの設定
  2. ApacheにServerAlias を設定
  3. VirutalDocumentRootを設定
  4. ディレクトリに権限を付与

これだけです。

0 : 準備

vhost_alias を使うのでモジュールを有効にしておきます。

sudo a2enmod vhost_alias

1:ワイルドカードドメインを設定

takuya-1st.example.com
takuya-2nd.example.com

などがすべて、同じサーバで拾えるような設定をします。

example.comワイルドカードを使うサンプル
example.comのエントリ
*               IN      A               192.168.1.123

これだけです。
ワイルドカードに対応したNameServerを使えば簡単です。ちなみに dyndnsやお名前com でも対応ているレベルです。ということで、殆どの場合どこでも使えます。

2.Apacheの設定

ドメインの設定がおわれば、つぎにApacheを設定します。

ServerAlias を設定して、既存のName Virutalホストが、一括でサーバ設定を受け取るように設定します

mod_vhost_alias をインストールして使えるようにする。

これは、殆どの場合のディストリに含まれているので何もしなくてもインストール済みで有効無効を切り替えるだけです。

3. ServerAlias の設定

ServerAliasをつかってApacheワイルドカードドメインに反応するようにします。

  ServerAlias  web.example.jp  *.example.com

これを、VirtualHostに書くと次のようになります。

NameVirtualHost *:80
<VirtualHost *:80>
  ServerName web.example.jp
  ServerAlias  web.example.jp  *.example.com
<VirtualHost *:80>

これでOK。つぎに、ディレクトリ名を決めます。

4.VirtualDocumentRootの設定。

VirtualDocumentRootが今回のエントリのキモになります。VirtualDocumentRoot を使えば、reweiteを使わずとも、設定が簡単になります。

 VirtualDocumentRoot /var/www/ex ample.com/%1/


コレを使うことがすべてのキモになります。

/var/www/example.com/takuya/ #---> takuya.example.com
/var/www/example.com/foo/ #---> foo.example.com

のように対応付けることができます。

出来上がった設定は、次のようになります。

NameVirtualHost *:80
<VirtualHost *:80>
  ServerName web.example.jp
  ServerAlias  web.example.jp  *.example.com
 VirtualDocumentRoot /var/www/example.com/%1/
<VirtualHost *:80>

なお、この便利な機能が mod_vhost_alias というモジュールになります。

最後に再起動

mod_vhost_alias をロードして設定を再起動します。

sudo a2enmod mod_vhost_alias
sudo service apache2 reload

これでめでたく、ホスト名を無尽蔵に増やすことができます。ドメイン設定不要になるのでとても楽ちんです。

これらの手間がゼロになり、ディレクトリ名の有無がドメイン設定になります。

これで出来上がった。

かんたんですね。

以下に実際に使っている例を出していきます。

応用例1:複数のドメイン
応用例2:サブドメインサブドメインをバージョン番号に
補足1:suExec
補足2:mod_proxy

などを実際に使っています。

応用例1 /home/$USERNAME/public_html

今回は、ドメインサブドメインディレクトリ名に見立てましたが。多数のユーザー名ドメインをまとめて面倒見る場合、これはどうしましょう

よく見かけるのが /home/$USERNAME/に持ってくる例。PLESKやHDEなどのホスティング・マネジャーにそのような機能があるから。この設定使われることが多い。それらと同じことをやりたいいばあいは、、、

 VirtualDocumentRoot /home/%1/public_html

になります。だけど、これパーミッションに注意が必要。home以下をまとめ公開するのはちょっとおすすめできない。

ホスト名有無=ディレクトリ有無=ユーザー有無

マッピングをしているので、ユーザーの有無がイコール、ドメインの有無になります。ドメインの有無とuseraddが直結するので管理が恐ろしく楽ちん。だけど諸刃の剣かも。ロリポップみたいなホスティングならいいんだけど、WEBアプリだけを動かすには向いてない。

応用例:複数のドメイン www.example.com ディレクト

沢山のドメインを扱う場合は、ドメイン毎にディレクトリ名をつけたら便利だと思います。

/var/www/www.example.com/
/var/www/ec.example.com/
/var/www/site1.example.com/
/var/www/auth.example.com/

のように、ドメイン単位ののホスティングが欲しい時。

 VirtualDocumentRoot /var/www/%0/public_html

のようにすれば良いと思います。%1 はサブドメイン、%0 はドメイン名全部を示します。

ただし、この場合でも、以下はお薦めしない

 VirtualDocumentRoot /var/www/%0/

のように、ディレクトリ名の直下を公開はちょっと躊躇う。非公開のデータ置き場がなくなる、、、うっかり公開しちゃうミスが起きそう。なのでかならず public_html フォルダを付けるようにする。

%1,2,3,4,5の例は次の通り。

sub.example.com の場合

%0 = sub.example.com
%1 = sub
%1+ = sub.example.com
%2 = example
%2+ = example.com

%A.B = %Aで指定されたドメイン部分のB文字目
%1.1 = s
%1.2 = u
%1.3 = b

%A.-B = %Aで指定されたドメイン部分の末尾からの文字数
%1.-1 = b
%1.-2 = u
%1.-3 = s

%A.B+ = %Aで指定されたドメイン部分の文字数から以降全て
%1.1+ = sub
%1.2+ = ub
%1.3+ = b

%1.-1+ = sub
%1.-2+ = su
%1.-3+ = s

http://www.artsnet.jp/archives/32

くわしくは、apache の公式Documentationにも書いてあります。

応用例2:サブドメインサブドメインも扱いたい

%2,%3が使えます。。。でも面倒なので、n個のサブドメインを扱うときは、原点に戻ってmod_rewrite を使うほうがいいかもしれない。

[takuya|takuya2].my.example.com を扱う設定

	RewriteEngine on
	RewriteMap    lowercase    int:tolower
	RewriteRule   ^/server-status - [L]
	RewriteRule   ^/icons/ - [L]
	RewriteCond   %{HTTP_HOST} ^(.+)\.(my\.example\.com)(:(80|443))?$
	RewriteCond   /var/www/%2/ -d
	RewriteRule   ^/(.*)$ /var/www/%2/%1/html/$1

これを書くことで、

/var/www/my.example.com/takuya #--> takuya.my.example.com
/var/www/my.example.com/www    #--> www.my.example.com
/var/www/my.example.com/test     #--> test.my.example.com

のように、サブドメインと、メインドメインディレクトリ名を使い分けられる、だけでなく

サブドメインをバージョン番号に使う。

応用例のサブドメインディレクトリ名にすることでとても便利になるのがバージョン番号です。

/var/www/my.example.com/ta.ku.ya #--> ta.ku.ya.my.example.com

などとと使うことができます。これはバージョンテストの時のドメインにとても便利です。

バージョン番号をドメインに使う例。

/var/www/my.example.com/4.2.1      #--> 4.2.1.my.example.com
/var/www/my.example.com/4.2.1.11 #--> 4.2.1.11.my.example.com
/var/www/my.example.com/5.x         #--> 5.x.my.example.com
/var/www/my.example.com/5.pre      #--> 5.pre.my.example.com
/var/www/my.example.com/6.4.1      #--> 6.4.1.my.example.com

などと、バージョン番号をそのままドメイン名に割り当てることができるので、バージョン管理システムとの相性が最高で、デプロイの手間がとても楽ちんになるのです。

git や subversion から定期的にバージョンの一覧を定期的にcheckout すれば、どのバージョンでも直ぐにチェック出来ますよ。

補足1:suExec と ScriptAlias

suExec は、/home/%1/public_html を使うときに重要になってきます。ユーザー名を使っているのでユーザー名での実行権限が大事になってきます。まぁこのへんはSuExecを理解してたら大丈夫だよね。

VirtualScriptAliasがあってScriptAliasの代わりに使えます。これもユーザー毎に変える場合に重要になってきますが、、、、mod_php だとApache共有なので関係ないですよね。CGI/fcgpモードで動かすときに大事です。

補足2: mod_proxyとNFS

これらの設定をmod_proxy と合わせると、大量のホスト名をホスティング可能になります。またNFSと併せて使えば、コンテンツの置き場所をドメインごとのネットワーク・サーバーに展開できて便利です。まぁiSCSI でも同じ事ですよね、NFSとか専用機でも買わない限り、新規でパフォーマンスを求めるLinux構成に使わないし。。。。




おまけ1:ワイルドカードドメインの負荷が予想される時

負荷が予想される時にDNSラウンドロビンをしたい場合は、CNAMEを使うといいんないでしょうか

*       IN      CNAME    web.example.com
web  IN      A             192.168.1.120
web  IN      A             192.168.1.121
web  IN      A             192.168.1.122
web  IN      A             192.168.1.123

と言った感じでしょうか。こんなかんじにしておけば、管理が楽になるんじゃないでしょうか。

直接IP接続の代わりに、 /etc/hosts 書き換えるようなことはやめましょう

/etc/hosts はできるかぎり使わないで、/etc/hosts の書き換えは控えましょう。その代わりにDNSMasqや今回のmod_vhost_alias を活用してはどうでしょうか。
せめてDNSサーバーで使いましょう。また、スマホサイトのCheckなど/etc/hosts 書き換えできないホストにもDNSサーバーの書き換えが一番楽だと思います。

/etc/hostsの書き換えはセキュリティホールに繋がるし、アンチウイルスソフトに怒られるので控えたほうが良いと思います。

感想など


テストサーバーを作るときや、バックアップサーバーの起動もcp -r コマンドで一発になります。

ほら、昔から言うじゃない?ApacheをOSだと思えって。Apacheが全て。仮想OSは下位インフラかな。

愚痴など

ドメイン1つずつにイチイチ仮想サーバーのインスタンス上げてるとかバカバカしい。仮想サーバーを作るだけの仕事スル人はみてて給与泥棒とおもう。すぐに仮想サーバー借りたりがる、作りたがる、管理コストあげるengineerは心が痛い。時間が惜しい。仮想サーバーって楽ちんなんだけど、バックアップとデプロイが手間なんですよね。DBはDBで、WEBはWEBでやればいい、PleskやWebminを使わないとApacheが設定できないというか、それくらいググらないengineerは滅び行く存在だと思います。Apacheの設定が出来ないならWEBプログラマ廃業してもいいかも。これくらいのApacheの初期設定&配備をテストチーム・メンテチームに役割分担してしまう組織もどうかと思います。ググったら直ぐ出てくるし、最低限書くことは5行です。a2enmod , ServerAlias , VirtualdocumenRoot,restart

サーバーを無駄遣いするのは、予算が潤沢にあるソフトハウスかハードベンダーなど大手IT企業出身がWEB屋に来た時によく見受けられる。餅は餅屋だというのですと大手ベンダ出身者のプライドを傷つけずに指摘するの面倒。なので僕は見てるだけ。僕は彼らのせいでサーバーが変わろうがssh_config で吸収するので面倒じゃないし、自前プロキシで切り替えるので面倒じゃないし、、、彼らはああいう面倒なことしてミスしないのが不思議でならない。手間やルールを増やしてもそれを社内ルールです従って下さいと言い切っちゃう発想が組織で生き方なんでしょうか。僕は彼らのようにデキるengineerではないので、邪魔されないようこつこつ自分の設定を蓄えていくだけです。。。

使っても減らない資産、それがノウハウ集と知識。むしろ使う度に増えていくのが知識とノウハウ。これを貯めないで、コピペ&お金で解決、そんな会社は滅び行くんだとおもいます。それがいやで大手を飛び出してきたんじゃないのかね。

参考資料

mod_vhost_alias - Apache HTTP Server Version 2.2


複数の名前でサーバアクセスができるようにしたいことも多いでしょう。 このようなことは、ServerAlias ディレクティブを セクションに記述することで実現できます。 例えば上記の の例であれば、 次のように一覧に挙げられた名前が、 ユーザが同一のウェブサイトとして目にして使用できるサーバ名である、 と ServerAlias ディレクティブで指定できます。

 ServerAlias domain.tld *.domain.tld

domain.tld ドメインへの全てのホストへのリクエストは www.domain.tld のバーチャルホストが処理します。 名前をマッチさせるために、ワイルドカード文字 * や ? を使用することもできます。もちろん思いつきの名前を作って、 ServerName や ServerAlias にその名前を書くといったことはできません。まずは、 これらの名前が サーバに付けられた IP アドレスにマップされるように DNS サーバを適切に設定しなければなりません。

http://httpd.apache.org/docs/2.2/ja/vhosts/name-based.html
ハウツー:Apacheでバーチャルホストを設定する | OSDN Magazine
NamevirtualHost *

ServerAdmin youremail@yoursite.com
DocumentRoot /srv/www/htdocs/directory_of_your_choice/
ServerAlias yourdomain.com *.yourdomain.com

http://sourceforge.jp/magazine/07/08/27/0148216
Apache でユーザごとの専用サブドメイン(ワイルドカードレコード) Kawanet Blog II/ウェブリブログ

DocumentRoot /var/www/default
RewriteEngine on
RewriteMap    lowercase    int:tolower
RewriteRule   ^/server-status - [L]
RewriteRule   ^/icons/ - [L]
RewriteCond   %{HTTP_HOST} ^(.+)\.(example\.com|example\.net)(:(80|443))?$
RewriteCond   /var/www/%2/%1 -d
RewriteRule   ^/(.*)$ /var/www/%2/%1/$1

http://kawa.at.webry.info/200811/article_5.html
VirtualDocumentRootを使って複数ドメインをスッキリ管理(Apache) - y-kawazの日記
NameVirtualHost *:80

  VirtualDocumentRoot /home/domains/%0/public_html


  Options All
  AllowOverride All

http://d.hatena.ne.jp/y-kawaz/20110725/1311610727
mod_vhost_aliasでサブドメイン動的生成 - Artsnet

    ServerAdmin info@example.com
    ServerName example.com
    ServerAlias *.example.com
    VirtualDocumentRoot /home/%2/public_html/%1
    ErrorLog logs/example.com-error_log
    CustomLog logs/example.com-access_log common

http://www.artsnet.jp/archives/32

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

VirtualDocumentRoot /home/%1/public_html
http://www.dabits.net/archives/3
livedoor Techブログ : CNAMEの間違った使い方
”CNAMEを設定したときは、他の全てのレコードを設定してはならない”

簡単に言えば、こういうことです。

CNAMEを設定するときに、他のレコードを登録しないようにしましょう。特に、NSレコードと同じにならないように注意が必要です。この設定の多くは、djbdns(tinydns)でみられます。djbdnsは設定内容に問題があってもエラー扱いとはならず、他のレコードも含めて問題に気が付きにくいという欠点を持ちます。また、djbdnsではCNAMEは使用可能であるものの推奨していません。その為か、CNAMEの扱いがいい加減という説もあります。

http://blog.livedoor.jp/techblog/archives/65340720.html

*1:とかいうなぞの作業をする人がいる