概要
CGI を任意のユーザー権限で実行したい場合に suEXEC を用いるが、ドキュメントルートに /home
以下を指定するなど /var/www
以外を使うと Apache のエラーログに End of script output before headers
のエラーが出力されて実行できない場合がある。
調査
End of script output before headers
/var/log/httpd/error_log
End of script output before headers: example.cgi
このエラーについては文字コードや改行コードなどについて記載されているページが多いが、本件では文字コードや改行コードとは無関係のようだ。
詳細は suEXEC のログが /var/log/secure
に記録されている。
command not in docroot
/var/log/secure
uid: (0000/example) gid: (0000/example) cmd: example.cgi
command not in docroot (/home/example/html/example.cgi)
docroot (AP_DOC_ROOT) の設定値
suexec -V
コマンドで設定値を確認できる。yum などでインストールした場合 AP_DOC_ROOT="/var/www"
となっている。この値は設定ファイルでは変更できず、コンパイル時に指定する以外に方法はない模様。
シンボリックリンクでは参照先を確認するため無理。ハードリンクではディレクトリーを指定できないため同様に無理。
suexec -V
-D AP_DOC_ROOT="/var/www"
-D AP_GID_MIN=100
-D AP_HTTPD_USER="apache"
-D AP_LOG_SYSLOG
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=500
-D AP_USERDIR_SUFFIX="public_html"
対策
mount --bind によるマウント
mkdir /var/www/example
mkdir /var/www/example/html
mount --bind /home/example/html/ /var/www/example/html/
chown example:example -R /var/www/example/html
fstab による自動マウント設定
cat << "_EOD_" >> /etc/fstab
/home/example/html /var/www/example/html none bind 0 0
_EOD_
VirtualHost の再設定
/etc/httpd/conf.d/virtual.conf
<VirtualHost *:80>
DocumentRoot /var/www/example
ServerName www.example.jp
SuexecUserGroup example example
ErrorLog "logs/example-error.log"
CustomLog "logs/example-access.log"
<Directory /var/www/example>
Options ExecCGI FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
リンク