suEXECに課される重い制約
最近、あるソフトウェアセキュリティーコンサルタントさんに「suEXECは必須だと思います」とアドバイスされました。suEXECというのはApacheでCGIの実効ユーザーを都合のいいユーザーに代えるための仕組みなわけですが、苦手な方多いんじゃないでしょうか?
「UIDが1000未満のユーザーはダメ(UID_MIN制約)」とか「suEXECで動かせるCGIは/usr/local/www/
の中に置いたものしか認めない(DOC_ROOT制約)」などの重い制約が課されるうえに、httpd.conf
等をいじって変えられるものでもありませんからね。
UID_MINとかDOC_ROOTとか、自分で決めたい
と思っても、意外と大変だったりします。
でもFreeBSD愛好家のアナタはツイている!
suEXECの設定はコンパイル時に固定されるので、バイナリパッケージでヌルく生きてる人はパッケージ制作者の決めたパラメーターに従うしかありません。でもFreeBSDユーザーなら問題なし!portsという強い味方がいるからです。
portsの強みは何といっても、その場でコンパイルしてくれるパッケージ管理ツールであること。それでいて、tarball持ってきて自力でconfigure make make-installするより遥かに簡単。素晴らしすぎます。
ただし、suEXECの設定に関してはちょっと知ってないと難しい。ということでこのTipsの出番です。
UID_MINとかDOC_ROOTとか自分で決めてインストール
では、次の要件でsuEXEC版インストールすることにしてみましょう。
UIDは500以上なら許可する(AP_UID_MIN=500)
GIDも500以上なら許可する(AP_GID_MIN=500)
CGIを動かしてよいディレクトリを
/home
以下にする(AP_DOC_ROOT=/home)許可するPATHを
/usr/local/mycommand:/usr/local/bin:/usr/bin:/bin
にする(AP_SAFE_PATH=/usr/local/mycommand:/usr/local/bin:/usr/bin:/bin)suEXECログ出力先を
/var/log/httpd/suexec.log
にする(AP_LOG_EXEC=/var/log/httpd/suexec.log)
a. make installの場合
portupgrade
とかを使っておらず、make install
で行う場合は次のように書けばOKです。
cd /usr/ports/www/apache24
make WITH_SUEXEC=yes SUEXEC_UIDMIN=500 SUEXEC_GIDMIN=500 SUEXEC_DOCROOT=/home SUEXEC_SAFEPATH=/usr/local/mycommand:/usr/local/bin:/usr/bin:/bin SUEXEC_LOGFILE=/var/log/httpd/suexec.log install
b. portupgradeを使っている場合
portupgrade
を使っている場合、-M
オプションを使えば同等のことができます。
portupgrade -M 'WITH_SUEXEC=yes SUEXEC_UIDMIN=500 SUEXEC_GIDMIN=500 SUEXEC_DOCROOT=/home SUEXEC_SAFEPATH=/usr/local/mycommand:/usr/local/bin:/usr/bin:/bin SUEXEC_LOGFILE=/var/log/httpd/suexec.log' -N www/apache24
c. portupgradeを使っている場合 その2(毎回書くのは面倒だ!)
アップグレードの度にportupgrade
コマンドにこの長い記述を書くのは面倒ですし、ホストに入っているパッケージ全体を一気にアップグレードしようとすると、せっかくの設定がその時に失われてしまいます。
ではどうすればいいかというと、/usr/local/etc/pkgtools.conf
のMAKE_ARGS変数内に書いておけば大丈夫です。
MAKE_ARGS = {
#:
'www/apache*' => [
'WITH_SUEXEC=yes',
'SUEXEC_UIDMIN=500',
'SUEXEC_GIDMIN=500',
'SUEXEC_DOCROOT=/home',
'SUEXEC_SAFEPATH=/usr/local/mycommand:/usr/local/bin:/usr/bin:/bin',
'SUEXEC_LOGFILE=/var/log/httpd/suexec.log',
],
#:
}
こうすればアップグレードの際、portupgrade
は必ず適用してくれますので、あとは普通にportupgrade
するだけです。
ちゃんと反映されているかな?
確認するにはsuexec
コマンドを-V
オプション付で実行すればわかります。
# suexec -V
-D AP_DOC_ROOT="/home"
-D AP_GID_MIN=500
-D AP_HTTPD_USER="www"
-D AP_LOG_EXEC="/var/log/httpd/suexec.log"
-D AP_SAFE_PATH="/usr/local/mycommand:/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=500
-D AP_USERDIR_SUFFIX="public_html"
他にどんなパラメーターが?
上記のように、suEXECには他にもいくつか設定できるパラメーターがあります。それらの一覧は次のようにすると調べることができます。
$ grep -R SUEXEC_DOCROOT /usr/ports/www
/usr/ports/www/apache22/Makefile.doc:## SUEXEC_DOCROOT: suEXEC root directory
/usr/ports/www/apache22/Makefile.doc
の中にそれらしきヘルプが記述されていることがわかりますので、開いてみると……
:
## WITH_SUEXEC: Enable suEXEC support
## SUEXEC_DOCROOT: suEXEC root directory
## SUEXEC_USERDIR: User subdirectory (default public_html)
## SUEXEC_SAFEPATH: Set the safepath
## SUEXEC_LOGFILE: Set log file for suEXEC (default: /var/log/httpd-suexec.log)
## SUEXEC_UIDMIN: Minimal allowed UID (default 1000)
## SUEXEC_GIDMIN: Minimal allowed GID (default 1000)
## SUEXEC_CALLER: User allowed to call suEXEC (default
## ${WWWOWN} (www))
## SUEXEC_UMASK: Defines umask for suEXEC'd process(default:
## unset)
:
いやぁ、portsって……、本当にいいものですね。