lighttpd+suEXECでCGIを動かす

lighttpd + fastcgi + suExecでtracを動かすを見て,普通のCGIでもいけるんじゃないの?と思ったのでやってみた.環境はCentOS-4.3.

まず,suEXECはlighttpdについてこないので,独自にビルドするかRPMで入れてやる必要がある.ところがRPMで提供されているsuEXECはAP_DOC_ROOT="/var/www"となっていて,ユーザー別のCGIを/var/www以下で動かすという,なんとも使いにくい設定になってしまっている.よって/home以下でsuEXECが使えるようにビルドし直すのが良いと思う.

suEXECのビルド

Apacheのビルド時にsuEXEC関連のオプションを指定する.自分が使ったsuEXEC関連のオプションだけ以下に.

$ ./configure \
  --enable-suexec \
  --with-suexec \
  --with-suexec-caller=apache \
  --with-suexec-docroot=/home \
  --with-suexec-logfile=/var/log/httpd/suexec.log \
  --with-suexec-bin=/usr/sbin/suexec \
  --with-suexec-uidmin=500 \
  --with-suexec-gidmin=500

出来上がったsuEXECの確認.

$ suexec -V
-D AP_DOC_ROOT="/home"
-D AP_GID_MIN=500
-D AP_HTTPD_USER="apache"
-D AP_LOG_EXEC="/var/log/httpd/suexec.log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=500
-D AP_USERDIR_SUFFIX="public_html"

suEXECとCGIの起動スクリプトを作成

こちらを参考に,suEXEC用と普通のCGI用の起動スクリプトを書いた.suEXECはshebangを解釈して良きに計らってくれる(はず).lighttpdCGIの実行に関して,拡張子とプログラムの対応を決め打ちで設定ファイルに書くが,shebangを見て自動でやって欲しいなーと思ったのでlighttpd-cgiというラッパーを書いてみた.

$ sudo vi /usr/sbin/llighttpd-suexec
#!/bin/sh

SUEXEC=/usr/sbin/suexec

DIR=`dirname $1`
SCRIPT=`basename $1`
USER=`stat -c '%U' $1`
GROUP=`stat -c '%G' $1`

cd $DIR
exec $SUEXEC $USER $GROUP $SCRIPT
$ sudo vi /usr/sbin/lighttpd-cgi
#!/bin/sh

SHEBANG=`perl -e 'print, last while <>' $1 | tr -d '#!'`
PATH="/usr/local/bin:/usr/bin:/bin" exec $SHEBANG $1

lighttpdの設定ファイルを変更

上記の起動スクリプトを使うようにlighttpdの設定を変更した.

$ sudo vi /etc/lighttpd/lighttpd.conf
server.modules += ( "mod_userdir" )

server.username = "apache"
server.groupname = "apache"

userdir.path = "public_html"
userdir.basepath = "/home/"

cgi.assign = ( ".cgi" => "/usr/sbin/lighttpd-cgi" )
$HTTP["url"] =~ "^/~.+/" {
  cgi.assign = ( ".cgi" => "/usr/sbin/lighttpd-suexec" )
}

設定は以上.これでlocalhost/hoge.cgiは(ユーザー名)apache権限で実行,localhost/~foo/bar.cgiはfoo権限で動くはず.ちなみにlocalhost/~foo/は/home/foo/public_htmlにマッピングされている.