tracは、チケットやWikiのデータを触ったり、subversionに触ったり、結構色々するプログラムである。httpdを動かしているユーザーにこれらの権限を与えたくないのでsuexecすることにする。
調べて分かったこと
lighttpdのパッケージにはsuexecは含まれていない。
lighttpd自体にはapacheの様にsuexecのパスを知っていたり、configuration次第で透過的にsuexecしてくれたり、そういう機能は無い。
fastcgiプログラムごとに、bin-pathに指定するしかない。
See Also:
やってみる
とりあえず、lighttpdのドキュメントに書いてあるphpの場合に合わせてやってみた。各pathはdebian sargeの場合。私はapache2-commonをインストールしたので実行ファイル名はsuexec2になってる。
起動スクリプトを用意
なんか、ドキュメントのやりかただとfastcgiプログラムごとに一々起動スクリプトが必要な気がするんだけど。
/usr/local/lib/trac/trac.fcgi.suexec にこんな感じのファイルを書いた。で、実行ビットを立てる。
#!/bin/sh user=trac group=trac cd /var/www/trac exec /usr/lib/apache2/suexec2 $user $group trac.fcgi
環境変数設定
/var/www/trac/trac.fcgi にこんな感じのものを置いた。suexecがコンパイル時規定の DOCUMENT_ROOT 外のスクリプトは拒絶するので、必ず /var/www 配下に置く。
#!/bin/sh exec env TRAC_ENV_PARENT_DIR=/var/trac /usr/share/trac/cgi-bin/trac.fcgi
このファイルは必ず、実行したいユーザーとグループの所有にしておく。でないとsuexecが拒絶する。
lighttpdの設定
で、あとは、bin-pathにさっきの起動スクリプトを設定。
fastcgi.server = (
"/trac" => (
"trac" => (
"socket" => "/var/run/fastcgi/trac.sock",
"bin-path" => "/usr/local/lib/trac/trac.fcgi.suexec",
"check-local" => "disable",
"bin-environment" => (
"TRAC_ENV_PARENT_DIR" => "/var/trac"
),
"min-procs" => 1,
"max-procs" => 4,
"idle-timeout" => 20
)
)
)
ちょっと直してみる
一応、上記がドキュメントに従った設定。でも、fastcgiプログラムごとに起動スクリプトを書くのは嫌な感じだ。で、こんなのを書いてみた。
/usr/local/lib/suexec/suexec.sh:
#!/bin/sh if [ "_$PATH_TRANSLATED" = "_" ]; then exit 1 fi DIR=`dirname $PATH_TRANSLATED` COMMAND=`basename $PATH_TRANSLATED` USER=`stat -c '%U' $PATH_TRANSLATED` GROUP=`stat -c '%G' $PATH_TRANSLATED` cd $DIR exec /usr/lib/apache2/suexec2 $USER $GROUP $COMMAND
lighttpdの設定も直す。
fastcgi.server = (
"/trac" => (
"trac" => (
"socket" => "/var/run/fastcgi/trac.sock",
"bin-path" => "/usr/local/lib/suexec/suexec.sh",
"check-local" => "disable",
"bin-environment" => (
"PATH_TRANSLATED" => "/var/www/trac/trac.fcgi"
),
"min-procs" => 1,
"max-procs" => 4,
"idle-timeout" => 20
)
)
)
/etc/init.d/lighttpd
なんか、suexec経由で走らせる様にしたら、lighttpdをstopするときにfastcgiプロセスが止まらずにinit(8)に引き継がれてしまう。止める直前に見てみるとfastcgiプロセスのPPIDはlighttpdになってるんだけど。このへんの挙動ってexecに影響されたっけ?
仕方がないから、/etc/init.d/lighttpdのstop処理部分をこんな風にしてみた。
stop)
log_daemon_msg "Stopping $DESC" $NAME
+ PID=`cat $PIDFILE`
+ SID=`ps -p $PID -o sid --no-headers`
if start-stop-daemon --quiet --stop --pidfile $PIDFILE --exec $DAEMON; then
+ PIDS=`ps -s $SID -o pid --no-headers`
+ if [ "_" != "_$PIDS" ]; then
+ kill -INT $PIDS > /dev/null
+ fi
rm -f $PIDFILE
log_end_msg 0
else
log_end_msg 1
exit 1
fi
;;