我正在运行 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
),使用SetHandler
和FilesMatch
代替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 的根目录。