表題の通り、Apache上で走るphpの権限を変える方法です。
最近だと、単目的で一つの仮想マシンを作ることが増えてきたのですが、一方で個人用でVPSをとりあえず借りて色々ごちゃごちゃと入れて使っている場合もあり、そういう場合はownCloudや重要なプロジェクトのWikiなど、扱う情報の重要度が高いプログラムだけでも権限を分けておきたいと思うことがあると思います。
suExecはバーチャルドメイン単位でしか使えませんし、そもそもphpにはそのままでは使えませんので(もちろん色々設定してsuExecを使う方法もあります)、suphpというモジュールをインストールすることにします。
ところが、suphpの0.7.2はportsにあるのですが、Apacheのバージョンが2.2以下じゃないとコンパイルできません。調べた所、いくつかパッチを当てれば動くので、手でコンパイルして入れることにしましょう。当然、portsのアップグレードでアップグレードされないので、最新版が出ているかどうかは別途自分で確認する必要があります。
さて、$ sudo su -: Compile and Install Apache-2.4.x + PHP-5.4.x + Suphp-0.7.1に、Linuxでの手順ですがApache 2.4でsuphp 0.7.1を動かす方法が書かれています。suphp 0.7.2、FreeBSDでもほぼこのまま行けましたのでこのままいきます。
基本的にはダウンロードしてパッチを当ててconfigureしてmake, make installです。途中でaprのincludeファイルをapache24ディレクトリにln -sする、あまり気分のよろしくない手順もありますが。
$ wget http://www.suphp.org/download/suphp-0.7.2.tar.gz $ tar xzvf suphp-0.7.2.tar.gz
configure.acの修正点
AC_CONFIG_FILES([Makefile src/Makefile src/apache/Makefile src/apache2/Makefile])
の行を次のように
AC_CONFIG_FILES([Makefile src/Makefile src/apache2/Makefile])
src/Makefile.amの修正点
if COND_AP13 MAYBE_AP = apache endif
を削除
SUBDIRS = $(MAYBE_AP) DIST_SUBDIRS = apache apache2
を
SUBDIRS = apache2 DIST_SUBDIRS = apache2
のように
以上の点を修正したら、configします。それぞれのバイナリの場所をwhichで調べて違ったら修正してください。Apacheがwww以外のユーザーで走っている時も修正してください。
$ ./configure \ --with-logfile=/var/log/suphp.log \ --with-apxs=/usr/local/bin/bin/apxs \ --with-php=/usr/local/bin/php-cgi \ --with-apr=/usr/local/bin/apr-1-config \ --with-setid-mode=paranoid \ --with-gnu-ld \ --disable-checkpath \ --with-apache-user=www
走りきったでしょうか。
続いて、includeが足りないと言われる件をどうにかします。あまり気分がよろしくないのですが、
sudo ln -s /usr/local/include/apr-1/* /usr/local/include/apache24
とかしてしまいます。もしこれなしでmakeが通るならそれに越したことはないので、先にこれなしでやってみるべきかもしれません。一応今回シンボリックリンクを貼ったファイルは全部aprで始まるようなので、完了後にapr*と指定すれば消すことはできます。
$ make $ sudo make install
インストールされると思います。
/usr/local/etc/suphp.confを書きます。
[global] ;Path to logfile logfile=/var/log/suphp.log ;Loglevel loglevel=info ;User Apache is running as webserver_user=www ;Path all scripts have to be in ;docroot=/var/www:${HOME}/public_html:/home/httpd/html/ ;Path to chroot() to before executing script ;chroot=/mychroot ; Security options allow_file_group_writeable=false allow_file_others_writeable=false allow_directory_group_writeable=false allow_directory_others_writeable=false ;Check wheter script is within DOCUMENT_ROOT check_vhost_docroot=true ;Send minor error messages to browser errors_to_browser=false ;PATH environment variable env_path=/bin:/usr/bin:/usr/local/bin ;Umask to set, specify in octal notation umask=0022 ; Minimum UID min_uid=0 ; Minimum GID min_gid=0 [handlers] application/x-httpd-php="php:/usr/local/bin/php-cgi" x-suphp-cgi="execute:!self"
最後にApache側の設定をする……のですが、その前に、phpファイルの所有者とグループは実際に走らせるユーザーのものになっていなければならないという制約があるので、先にchown, chgrpコマンドで目的のものに変更しましょう。これはconfigureの段階で変更することもできるのですが、危険なのでやってはいけないとsuphpのドキュメンテーションのインストールのところの–with-setid-mode=MODE:のところに書いてあります。理由については触れられていませんが、.htaccessを自由に使える設定の場合そのファイルの所有者が好きな権限で走らせることができるからでしょうか。
httpd.conf内の、php5モジュールを読み込む行をコメントアウトします。
/usr/local/etc/apache24/Includes/suphp.confに以下のように書きます。
oadModule suphp_module libexec/apache24/mod_suphp.so suPHP_Engine on AddType application/x-httpd-php .php suPHP_AddHandler application/x-httpd-php suPHP_UserGroup www www
もちろん、デフォルトでwww以外のユーザー/グループで走らせたい人は変えてもよいでしょう。実際に、別のシステムアカウントを作ってそちらにすることにしました。
権限を変えてphpを走らせたいところの設定ファイルに
suPHP_UserGroup user group
を書きましょう。
また、apache2 – suphp error Directory / is not owned by admin – Server Faultに書かれているように、親ディレクトリを遡っていった時にrootでもそのユーザーでもない所有者のディレクトリがあった時に警告が出て実行できないそうです。そのユーザーのフォルダのすぐ上のフォルダはrootを所有者にしておきましょう。
余談ですが、先ほど登場したシステムユーザーの追加はFreeBSD/ユーザーの追加 – BugbearR’s Wikiを参照してください。UIDを1000未満、ログインシェルをnologin、ホームディレクトリを/nonexistent、パスワード認証なしにすればよいそうです。
これで、phpのユーザーをアプリケーションごとに走らせることができました。もちろん、別の仮想マシンを使ったりjailを利用したりするほうが安全ではありましょうが、そこまでするのも仰々しいなぁ……と思う場合にはバランスのとれた選択肢なのではないでしょうか。
# にしてもportsのコンパイラもapache24に対応してくれないかなー。