mod_vhost_alias/mod_lua編#Apache#Lua大瀧隆太2013.12.30199348この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。小規模なWebサイトの運用は、「お金はかけられないけど、ハードウェア障害などでサイトが落ちると困る」というように、運用コストが問題になりやすいITシステムではないでしょうか。そんなシステムへのソリューションとして、運用コストを削減できるクラウドの利用とWebサーバー集約は案件として最近よく耳にします。Hostingが挙げられますが、BASIC認証に対応しておらず企業や会員向けサイトなどでは要件が満たせないことがあります。httpd(以下Apache)を実行し、Webサーバーの集約としてバーチャルホストを構築するレシピをご紹介します。*1および<VirtualHost>ディレクティブで設定できますが、これらの情報はWebに溢れているため今回は敢えて書きません!これらの方法だと、バーチャルホストの数だけディレクティブを定義しなければならないため、運用面で以下の問題があります。バーチャルホストの設定を追加する度に、Apacheの再起動が必要バーチャルホストの設定がひとつでも間違っているとApache自体が起動しないため、全サイトが動かなくなるサイト数が増えてくると、恐怖の運用が待っていることがイメージできると思います。そこで、再起動の必要がない方法を模索しました。2.2からサポートされている比較的新しいモジュールです。モジュールを有効にすると、VirtualDocumentRootディレクティブでバーチャルホストごとに異なるドキュメントルートを設定できます。ドキュメントルートのパスには変数を含めることができ、%0がドメイン名に置換されます。Linuxのhttpd24パッケージであれば、既定でmod_vhost_aliasモジュールが有効なので、例えば/etc/httpd/conf.d以下に設定ファイルを追加し構成できます。]$これにより、/var/www/vhost/<ドメイン名>/htmlがドメインごとのドキュメントルートとして動作します。適当なファイルを配置し、動作を確認してみます。example.comを追加し、ブラウザでアクセスしてみました。表示されました!これでコンテンツをドメインごとに分割できますが、mod_vhost_aliasモジュールではドキュメントルート以外にScriptAliasしか設定できないため、従来のバーチャルホスト機能と比較すると以下の問題点があります。アクセスログ、エラーログがバーチャルホスト単位で分割できない。バーチャルホストの対象となるドメインを絞り込めない。あと一歩、かゆいところに手が届かないという印象です。設定自体はとても簡単ですし、Apacheの設定変更なしでドメインをどんどん増やしていけるので簡易バーチャルホストとしては強力な機能だと思います。mod_luaモジュールmod_luaは、mod_perlやmod_phpと同様にApacheでLua言語を実行するモジュールですが、今回はCGIとしての実行ではなく、Apacheの動作をフック、カスタマイズする用途で利用します。VirtualBoxで検証しました。EC2でも同様でしょう。mod_luaを有効にしApacheをインストールします。install続いて、mod_luaでApacheの動作をフックするハンドラを定義します。ハンドラ定義はApacheの動作のうちカスタマイズしたいタイミングによって、以下のディレクティブをApacheの設定ファイルに記述します。URIからファイル名を解釈するタイミング。物理、キャッシュ、プロキシなどストレージを解釈するタイミング。クライアントがリソースにアクセスできるかどうかを評価するタイミング。コンテンツ処理後のログ処理のタイミング。今回はバーチャルホストの動作としてURIの解釈とログ処理をフックするために、LuaHookTranslateNameディレクティブ、LuaHookLogディレクティブでそれぞれハンドラを登録します。バージョン2.4.6がほとんどだったため、LuaHookLogディレクティブを使うためにソースからインストールしました。バーチャルホストのディレクトリレイアウトは、以下にしてみました。granted</Directory>Luaスクリプト側の実装はとてもシンプルで、上記で定義したハンドラに対応するハンドラ関数をスクリプトに記述するだけです。実装のポイントは、ハンドラ関数の引数になるrequest_rec構造体とapache2パッケージです。request_rec構造体ハンドラ関数で受け取る引数に代入される構造体です。クライアントのリクエスト情報など、Apacheのデータを参照するために利用します。多くのコードサンプルでは変数rで受け取り、r.hostname(リクエストのホスト名)やr.uri(リクエストのURI)として参照します。詳細はmod_luaガイドにありますが、未実装でエラーになるのものもあることに注意します。mod_luaapache2パッケージ実行しているApacheの情報が取れるパッケージです。現状はバージョン番号と、Apacheの動作をコントロールする以下の定数(これ重要)を参照できます。定数は、主に以下をハンドラ関数のreturn文に指定して使用します。リクエスト処理の終了を示す。Apacheの既定の動作を示す。"luaスクリプトではApacheの動作設定などを変更し、レスポンスはApacheのコンテンツを返す"というような場合に指定するapache2パッケージの詳細はApacheドキュメントで参照できますが、そのページにあるサンプルスクリプトBuggyで動作しないものもある(バーチャルホストのサンプルはエラーになりました)ので、注意してください。Serverバーチャルホストの実装例ではコードを示してみます。ドキュメントルートを変更するvhost.luaから。apache2.DECLINEDend続いて、ログをフックするvhost-log.luaを。apache2.DECLINEDendアクセスログは、request_rec構造体からリクエストの情報を取り出してApacheのcombinedログに整形しています。レスポンスのバイトサイズは見当たらなかったので未実装としました。-を仮の値として入れています。それからエラーログも見つからなかったため、実装できていません。Safari/537.36"$きっちりアクセスログとして書き出されていますね!まとめmod_luaモジュールはステータスがまだexperimentalで、ドキュメントに記載があっても動作しない機能があったり発展途上な感もありますが、Apacheの動作をカスタマイズする手段として期待できる印象が持てました。今後もウォッチしていきたいと思います。Apacheの拡張として最近ホットなmod_mrubyも、そのうち検証してみたいです。いえば、Nginxだと標準機能で今回のmod_lua相当のバーチャルホストが構成できるようなので、そちらも試してみないと。脚注Apacheバージョン2.4以降では定義不要になり、<VirtualHost>ディレクティブのみで動作します。