Apache:设置 php-fpm chroot 后出现“服务不可用”

Apache:设置 php-fpm chroot 后出现“服务不可用”

我正在运行 Debian Jessie 和 Apache 2.4.10。我遇到了“文件未找到”问题,最后参考了这个问题。我的设置和他的设置之间的唯一区别是,我真的(出于各种原因)更喜欢使用 UDS 而不是 TCP 套接字,并且使用 ProxyPassMatch 解决方案并不能完全解决问题,尽管我不确定为什么。

以下是我的配置行:

ProxyPassMatch "^/(.*\.php)$" "unix:/var/run/myappname.sock|fcgi://localhost/webroot/$1"

以下是调试输出:

AH00944: connecting fcgi://localhost/webroot/index.php to localhost:8000, referer: http://myapp.com
AH00947: connected /webroot/index.php to localhost:8000, referer: http://myapp.com
(111)Connection refused: AH00957: FCGI: attempt to connect to 127.0.0.1:8000 (*) failed

如果我尝试使用除 之外的地址,例如,localhost我会遇到 DNS 故障,但是当使用 时SetHandler,我可以成功使用任意字符串作为地址。我不明白其中的区别。这是一个工作示例(没有chroot),使用SetHandlerFilesMatch代替ProxyPassMatch

<FilesMatch "\.php$">
    SetHandler "proxy:unix:/var/run/myappname.sock|fcgi://myappname/"
</FilesMatch>

答案1

使固定

有一个比在 chroot jail 内建立符号链接树更好的解决方案。

而不是这样:

ProxyPassMatch "^/(.*\.php)$" "unix:/var/run/myappname.sock|fcgi://localhost/webroot/$1"

用这个:

ProxyPassMatch "^/(.*\.php)$" "unix:/var/run/myappname.sock|fcgi://localhost/webroot"

简而言之,删除/$1末尾的,这是不必要的。对于其他版本的 Apache 来说,这可能是必需的,但至少对于 2.4.25 来说,该位将导致503您描述的错误。

ProxyPassMatch对比FilesMatch

FilesMatch和 的区别在于ProxyPassMatch后者向 fcgi 进程传递一个相对脚本路径,而前者发送 Apache 所看到的完整路径,其中包括到 chroot 所在位置的路径。

调试

使用该strace命令有助于调试此问题。当 PHP 工作进程尝试读取文件时,跟踪将显示它尝试读取的文件的完整路径。

使用FilesMatch

lstat("/srv/jail/var/www/index.php", 0x7ffeb3069390) = -1 ENOENT (No such file or directory

由于 PHP 工作进程被限制在里面/srv/jail,因此命令失败。

使用ProxyPassMatch

lstat("/var/www/index.php") {st_mode=S_IFREG|0644, st_size=96, ...}) = 0

该过程成功读取文件。

您可以strace按以下方式启动,它将输出 php-fpm 及其子/工作进程的跟踪:

strace -f $(pgrep -f php-fpm | sed 's/\([0-9]*\)/\-p \1/g')

答案2

我尝试了很多不同的方法来实现这一点,主要是试图避免回到这个已知方法最终,这是我唯一成功的方法。

cd /full/path/to/chrootdir
mkdir -p full/path/to
cd full/path/to
# only as many dots as your setup requires
ln -s ../../.. chrootdir

对我来说最适合使用的SetHandler

<FilesMatch ".*\.php$">
    SetHandler "proxy:unix:/var/run/php-fpm-myapp.sock|fcgi://myapp"
</FilesMatch>

最后,这并不是太糟糕,而且对于我来说,回报是值得的。

解释:mod_proxy_fcgi 传递 php 脚本的完整路径。因此,php-fpm 收到解释文件的指令/full/path/to/chrootdir/script.php,但由于该文件位于 chroot jail 中,因此无法找到该文件。相对符号链接将完整路径链接回 chroot jail 的根目录。

相关内容