Apache:设置php-fpm chroot后,找不到“File Not Found”

我在使用CentOS 7运行Apache 2.4的php-fpm上实现chroot的最后一步很苦恼。

我已经成功安装并testing了没有chroot的php-fpm连接。 但是一旦我将chroot指令添加到/etc/php-fpm.d/file.conf中的conf文件中,就会得到一个“File Not Found”, 就像其他人所经历的一样 。

这是我的php-fpm conf文件:

[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根目录。 (系统path是/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错误日志文件中没有任何显示。

所以,毕竟,

  • 为什么我仍然收到“文件未find”的错误信息?
  • 更好的是,我该如何解决这个问题,或者至less,我怎样才能更好地解决我的问题?

php-fpm有一个chroot和path的bug。

例如在www中使用index.php

 chroot = /home/www/site1.com chdir = /www 

用这个configurationphp-fpm写这个path:

 /home/www/site1.com/home/www/site1.com/www 

一个解决scheme是在shell中创build一个符号链接:

 cd /home/www/site1.com mkdir -p home/www cd home/www ln -s /home/www/site1.com site1.com 

但它不干净。

https://bugs.php.net/bug.php?id=55322

https://bugs.php.net/bug.php?id=62279

你有SElinux启用? getenforce应该能够告诉你这一点。 如果是这样的话,setenforce 0会禁用它,然后你需要编辑/ etc / sysconfig / selinux并将SELINUX设置为禁用,以便在重新启动后持久化。

这已经解决了。 我的上面的代码有两个问题。

问题#1 – 只有Apache 2.4.10及以上版本可以支持套接字

基础CentOS仓库( Apache 2.4.6 )中默认的Apache版本只支持TCP端口。 因此上面的代码是不正确的,php-fpmconfiguration文件中的listen指令需要更改为如下所示:

 listen = 127.0.0.1:9001 

我也在http.dconf文件中做了适当的修改,另外,我还切换到了使用ProxyPassMatch指令而不是使用FilesMatch指令。 所以我的代码变成了:

 ProxyPassMatch "^/(.*\.php)$" "fcgi://127.0.0.1:9001/site1.com" 

请注意,这个代码仍然是错误的…见下文

继续…

问题#2 – 相关path

ProxyPassMatch指令中的path(或者,在使用FilesMatch指令的旧代码的情况下)在我的http.dconf文件中变得相对于chroot 。 它不相对于www文档根(如果不同)。

所以我的代码在我的http.d conf文件变成:

 ProxyPassMatch "^/(.*\.php)$" "fcgi://127.0.0.1:9001/www/$1" 

瞧! 我有一个php-fpm chroot。

有些人可能因为2件事而收到这个错误。

  • 在php.ini中错误的相对path
    如果您在PHP-FPM.conf中指定了open_basedir,doc_root,user_dir,session.save_path,upload_tmp_dir(及其他),那么这些path必须与chroot相关。
    例如:

chroot = / var / www
php_admin_value [doc_root] = / htdocs
;所有的path必须相对于chroot,因为在chroot之后,PHP并不知道绝对path

  • cgi.fix_pathinfo = 1在php.ini
    TL; DR只是将其更改为0。
    由于某些原因,这个值会影响你的PHP-FPM,即使这个参数只适用于CGI。
    你应该阅读更多的关于这个参数,因为它可能会打破其他的东西,更在这里