我正在努力实现在 CentOS 7 上运行 Apache 2.4 的 php-fpm 上的 chroot 的最后一步。
我有设置成功和已测试php-fpm 连接无需 chroot。但是,当我将 chroot 指令添加到 /etc/php-fpm.d/file.conf 中的 conf 文件中时,我收到“文件未找到”正如许多其他人所经历的那样。
这是我的 php-fpm 配置文件:
[site1.com]
user = user1
group = user1
listen = /var/run/php-fpm/site1.com.sock
listen.owner = user1
listen.group = user1
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = on
php_admin_value[short_open_tag] = On
php_admin_value[doc_root] = /
php_admin_value[error_log] = /logs/php-errors
php_admin_flag[log_errors] = on
pm = ondemand
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chroot = /home/www/site1.com
chdir = /www
catch_workers_output = yes
如您所见,设置 chroot 后,我更改了chdir
指令,使其与 PHP 根目录相关。(系统路径将是/home/www/site1.com/www
,这是chdir
在启用指令之前设置的路径chroot
)。
这是我的相关 http.d/site1.conf 文件:
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName site1.com
ServerAlias www.site1.com
DocumentRoot /home/www/site1.com/www
<Directory "/home/www/site1.com/www">
Options Includes FollowSymLinks
DirectoryIndex index.php
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorLog /home/www/site1.com/logs/errors
CustomLog /home/www/site1.com/logs/access_log common
<FilesMatch "\.php$">
SetHandler "proxy:unix:///var/run/php-fpm/site1.com.sock|fcgi://site1.com"
</FilesMatch>
LogLevel trace3
</VirtualHost>
我已经在 httpd.d/site.conf 文件中提高了 LogLevel,以下是一些有趣的输出:
[Mon Nov 02 10:42:52.665284 2015] [proxy:trace2] [pid 14286] proxy_util.c(2007): [client 74.221.189.99:16486] *: found reverse proxy worker for unix:///var/run/php-fpm/site1.com.sock|fcgi://site1.com/home/www/site1.com/www/index.php
[Mon Nov 02 10:42:52.665292 2015] [proxy:trace2] [pid 14286] proxy_util.c(2041): [client 74.221.189.99:16486] *: rewrite of url due to UDS(/var/run/php-fpm/site1.com.sock): fcgi://site1.com/home/www/site1.com/www/index.php (proxy:fcgi://site1.com/home/www/site1.com/www/index.php)
[Mon Nov 02 10:42:52.665295 2015] [proxy:debug] [pid 14286] mod_proxy.c(1117): [client 74.221.189.99:16486] AH01143: Running scheme unix handler (attempt 0)
[Mon Nov 02 10:42:52.665300 2015] [proxy_ajp:debug] [pid 14286] mod_proxy_ajp.c(713): [client 74.221.189.99:16486] AH00894: declining URL fcgi://site1.com/home/www/site1.com/www/index.php
[Mon Nov 02 10:42:52.665304 2015] [proxy_fcgi:debug] [pid 14286] mod_proxy_fcgi.c(948): [client 74.221.189.99:16486] AH01076: url: fcgi://site1.com/home/www/site1.com/www/index.php proxyname: (null) proxyport: 0
[Mon Nov 02 10:42:52.665307 2015] [proxy_fcgi:debug] [pid 14286] mod_proxy_fcgi.c(955): [client 74.221.189.99:16486] AH01078: serving URL fcgi://site1.com/home/www/site1.com/www/index.php
[Mon Nov 02 10:42:52.665311 2015] [proxy:debug] [pid 14286] proxy_util.c(2200): AH00942: FCGI: has acquired connection for (*)
[Mon Nov 02 10:42:52.665316 2015] [proxy:debug] [pid 14286] proxy_util.c(2253): [client 74.221.189.99:16486] AH00944: connecting fcgi://site1.com/home/www/site1.com/www/index.php to site1.com:8000
[Mon Nov 02 10:42:52.665320 2015] [proxy:debug] [pid 14286] proxy_util.c(2286): [client 74.221.189.99:16486] AH02545: fcgi: has determined UDS as /var/run/php-fpm/site1.com.sock
[Mon Nov 02 10:42:52.665420 2015] [proxy:debug] [pid 14286] proxy_util.c(2419): [client 74.221.189.99:16486] AH00947: connected /home/www/site1.com/www/index.php to httpd-UDS:0
[Mon Nov 02 10:42:52.668135 2015] [proxy_fcgi:error] [pid 14286] [client 74.221.189.99:16486] AH01071: Got error 'Primary script unknown\n'
[Mon Nov 02 10:42:52.668179 2015] [proxy_fcgi:trace1] [pid 14286] util_script.c(599): [client 74.221.189.99:16486] Status line from script 'index.php': 404 Not Found
[Mon Nov 02 10:42:52.668237 2015] [http:trace3] [pid 14286] http_filters.c(992): [client 74.221.189.99:16486] Response sent with status 404
[Mon Nov 02 10:42:52.668284 2015] [proxy:debug] [pid 14286] proxy_util.c(2215): AH00943: FCGI: has released connection for (*)
php 错误日志文件中未显示任何内容。
经过这一切之后,
- 为什么我仍然收到“未找到文件”错误消息?
- 更好的是,我该如何修复它,或者至少,我该如何更好地解决我的问题?
答案1
问题已解决。上面的代码有两个问题。
问题 #1 - 只有 Apache 2.4.10 及以上版本支持套接字
基本 CentOS 存储库中的 Apache 默认版本(Apache 2.4.6) 仅支持 TCP 端口。因此,上述代码是不正确的,listen
php-fpm 配置文件中的指令需要更改为如下内容:
listen = 127.0.0.1:9001
我也在 http.d conf 文件中做了相应的更改,但此外,我还切换到使用指令ProxyPassMatch
而不是使用指令FilesMatch
。所以我的代码变成了:
ProxyPassMatch "^/(.*\.php)$" "fcgi://127.0.0.1:9001/site1.com"
请注意,此代码仍然是错误的...见下文
继续...
问题 #2 - 相关路径
我的 http.d conf 文件中的指令中的路径ProxyPassMatch
(或者,在我较旧的使用该指令的代码中)变为相对路径FilesMatch
到 chroot。它与 www 文档根目录无关(如果不同)。
因此我的 http.d conf 文件中的代码变成:
ProxyPassMatch "^/(.*\.php)$" "fcgi://127.0.0.1:9001/www/$1"
瞧!我有一个 php-fpm chroot。
答案2
php-fpm 的 chroot 和路径存在错误。
例如 www 中的 index.php
chroot = /home/www/site1.com
chdir = /www
使用此配置 php-fpm 写入此路径:
/home/www/site1.com/home/www/site1.com/www
一个解决方案是在 shell 中创建一个符号链接:
cd /home/www/site1.com
mkdir -p home/www
cd home/www
ln -s /home/www/site1.com site1.com
但它不干净。
答案3
有些人可能会因为两件事而收到此错误。
- php.ini 中的相对路径错误
如果您在 PHP-FPM.conf 中指定 open_basedir、doc_root、user_dir、session.save_path、upload_tmp_dir(及其他),则这些路径必须相对于 chroot。
例如:
chroot = /var/www
php_admin_value[doc_root] = /htdocs
;所有路径必须相对于 chroot,因为 chroot 之后 PHP 不知道绝对路径
- cgi.fix_pathinfo = 1 in php.ini
TL;DR 只需将其更改为 0。
出于某些原因,此值会影响您的 PHP-FPM,即使此参数仅适用于 CGI。
您应该阅读有关此参数的更多信息,因为它也可能破坏其他内容,更多这里
答案4
经过一天与 php-fpm 和 chroot 的斗争,我设法修复了基于 Apache 的 PHP-FPM 和 chroot这个答案
添加了这些值
/etc/php/8.2/fpm/pool.d/my-pool-conf.conf
chroot = /home/my-user-home-dir chdir = /public_html php_admin_value[doc_root] = /public_html php_admin_value[open_base_dir] = /public_html:/tmp php_admin_value[doc_root] = /public_html
我
/etc/php/8.2/fpm/php.ini
改变了这个:cgi.fix_pathinfo=0
我找到了几个建议使用 更改 Apache 指令的答案SetHandler
,ProxyPassMatch
但目前这并没有什么区别,两者似乎都在起作用