FreeBSD上のApache 2.4で走るphpプログラムの権限変更(suphp)

表題の通り、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に対応してくれないかなー。