suEXEC 替代方案:ExecWrap¶
本页面的其余部分专门讨论随 Apache Web 服务器分发的 suEXEC 代码以及 PHP:我们希望 PHP 以目标用户身份执行。
Apache suEXEC¶
参阅 suEXEC 文档简而言之,suEXEC 会确保一切正常,清理环境并确保满足某些条件,然后执行 setuid。suEXEC 检查的内容包括:
- 您将执行的脚本属于目标用户/组,并且任何其他人均无法修改它;
- 该脚本所在的目录属于目标用户/组,并且任何人都无法在该目录中写入任何内容;
- suEXEC 是从这个目标目录启动的。
因此,涉及到相当多的封装:在某个时刻,您需要将当前目录更改为目标目录以启动 suEXEC,并且启动一个(属于目标)用户脚本最终会启动 php 可执行文件会更简单。
所以有两个脚本在中间,这相当笨拙。好的一面是它非常灵活。
Lighttpd 配置¶
lighttpd.conf 包含以下内容
$HTTP["host"] =~ "^mywebsite.org$" { fastcgi.server = ( ".php" => ( "localhost" => ( "socket" => "/var/run/fastcgi/myuser.socket", "bin-path" => "/usr/local/etc/suexec/myuser.sh", "idle-timeout" => 30, "min-procs" => 3, "max-procs" => 10, "max-load-per-proc" => 4 ) ) ) }
/usr/local/etc/suexec/myuser.sh
是将启动 suEXEC 的脚本(见下文)。/var/run/fastcgi/
是将包含 lighttpd 用于与 FastCGI 后端通信的 UNIX 套接字的目录。重要的是只有 www 用户才能在该目录中写入。
封装 suEXEC¶
因此,lighttpd 会不时运行 /usr/local/etc/suexec/myuser.sh
。lighttpd 必须能够执行此脚本。此脚本负责启动 suEXEC 所需的操作:切换到目标目录。
/usr/local/etc/suexec/myuser.sh
:
#!/bin/sh user=myuser group=mygroup cd /usr/local/www/data/$user /usr/local/sbin/suexec $user $group php.sh
请注意:/usr/local/www/data/
并非随意选择——suEXEC 只接受在运行时配置的特定目录中运行脚本。根据您运行的发行版,它可能会有所不同。请以 root 身份运行 suexec -V 以确认。
$ sudo suexec -V -D DOC_ROOT="/usr/local/www/data" -D GID_MIN=1000 -D HTTPD_USER="www" -D LOG_EXEC="/var/log/httpd-suexec.log" -D LOGIN_CAP -D SAFE_PATH="/bin:/usr/bin:/usr/local/bin" -D UID_MIN=1000 -D USERDIR_SUFFIX="public_html"
脚本必须位于您在此处看到的 DOC_ROOT 目录中。
用户的脚本:php.sh¶
该脚本及其所在的目录必须属于目标用户/组(此处,
myuser 和 mygroup)。
/usr/local/www/data/myuser/php.sh
:
#!/bin/sh exec /usr/local/bin/php
为安全起见,您可能需要
chown -R myuser:mygroup /usr/local/www/data/myuser/
故障排除¶
除了 lighttpd 日志文件外,有关情况的信息可在 /var/log/httpd-suexec.log 文件中找到(请参阅 suexec -V 的输出,您的可能不同)。通常,问题与文件的权限和所有权有关。