はちゅにっき

こっちのブログはまったり更新

特定の VirtualHost でのみ SuEXEC したい

必要かといえば、そんなに必要性はないのですが。
自分の開発環境として、ホームディレクトリ以下の "/home/my/dev" を DocumentRoot とするような VirtualHost を設定していますが、これだと実行されるスクリプトは Apache で設定してあるユーザ権限 *1 で動作することとなります。
そのため、パーミッションの設定などが煩雑になっており*2、そのくらいならば SuEXEC して、開発環境だけは自分のユーザ権限で全部動けば楽かなぁと思った次第です。
UserDir を用いるなど、解決*3方法はいろいろあるかとは思いますが。。。

VirtualHost の設定

この先少しはまったので、はまらないであろう VirtualHost の設定から先に書きます。

  • /etc/apache2/sites-available/suexec_vhost
# dev.mydomain.jp
<VirtualHost *>
    SuexecUserGroup myuser mygroup  # ← SuEXEC で動作させるユーザとグループ
    ServerName   "dev.mydomain.jp"
    DocumentRoot "/home/my/dev"

    # だらだらといろいろな設定
    # 実際は Catalyst を mod_perl で動かす設定など書いてあります

</VirtualHost>
  • 設定ファイルを有効にする
# a2ensite suexec_vhost
# /etc/init.d/apache2 force-reload


VirtualHost の設定はこれで終了。
つまりは "SuexecUserGroup" を書き足した以外は、特に普通の設定と変わらないですね。

SuEXEC のインストールと設定

の前に、先にパターン分けを。

  • apache2-suexec-custom が
    1. インストールできる (利用できる)
    2. インストールできない (利用できない)

で、だいぶ設定が変わるというか、はまるというか。
apache2-suexec-custom がインストールできれば非常にカンタンです。

suexec-custom が利用できる場合

  • インストール
# aptitude install apache2-suexec-custom
# a2enmod suexec

どのディレクトリ以下で SuEXEC を有効にするかの設定をします。

  • /etc/apache2/suexec/www-data
/home/my/suexec/path
# ↑ SuEXEC で動作させたいディレクトリへのパスをかく
#  ここに書いたディレクトリ以下では SuEXEC で動作する (設定していれば)
#  public_html/cgi-bin  とか書くと、"*public_html/cgi-bin/*" として解釈してくれるみたい
  • 再起動する
# /etc/init.d/apache2 force-reload

これで動くようになりました。

suexec-custom が利用できない場合

  • インストール
# aptitude install apache2-suexec
# a2enmod suexec

ここからが問題。
suexec-custom がインストール出来る場合は "/etc/apache2/suexec/www-data" に SuEXEC で動作させたいディレクトリのパスを書くことで設定が完了したのですが、suexec-custom を利用出来ない場合は、apache をコンパイルする際にあらかじめ指定したパスでしか SuEXEC が動作しません。
当然 aptitude でインストールしているため、その指定を変更することができません。*4
で、コンパイル時に指定してあるパスは "/var/www" となっています。
つまり "/var/www" 以下のディレクトリでなければ SuEXEC が動作しないことになります。
もし、関係ないところで SuEXEC しようとする (たとえば "/home/my/dev" で実行しようとする)と、error.log にもれなく

  • error.log
suexec policy violation: see suexec log for more details

と表示されます。また、suexec.log の方には

  • suexec.log
command not in docroot (/home/my/dev/hoge.cgi)

などと表示されてしまいます。
とゆーわけで、解決方法としては

  1. あきらめて "/var/www" 以下で作業をする
  2. 気合いでなんとかする

となりますが、あきらめる方向には進みたくないので、気合いでなんとかすることに。
とはいっても、結局 /var/www 以下に実態があればいいので (シンボリックリンクではだめだった) むりやり実態を mount するという荒技に出ました。

# pwd
/var/www/
# mkdir mnt
# mount --bind /home/my/dev /var/www/mnt

これで "/var/www/mnt" 以下に、"/home/my/dev" 以下の内容が mount されるため、無事に SuEXEC で動作するようになりました。
当然、--bind をつけて mount しているので、もとの "/home" がどっか吹っ飛んじゃったり、"/var/www/mnt" と "/home" が違うモノになっちゃったりはしません。
と、いうわけで設定を反映させるために再起動します。

  • 再起動する
# /etc/init.d/apache2 force-reload

これで、きちんと SuEXEC で動作させることができるようになりました。
やったね。

*1:Debian 的には www-data

*2:my ユーザのホームディレクトリ以下で www-data ユーザがごにょごにょと実行するため

*3:解決というより、回避といったほうが正しいかもしれません

*4:deb パッケージをダウンロードしてごにょごにょする場合は除きますが。