I'm struggling with the final step in implementing a chroot on php-fpm with Apache 2.4 running on CentOS 7.
I've successfully setup and tested the php-fpm connection without the chroot. But as soon as I add the chroot directive into my conf file in /etc/php-fpm.d/file.conf, I get a "File Not Found" as many other people have experienced.
Here's my php-fpm conf file:
[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
As you can see, after I set the chroot, I changed the chdir
directive so that it is relative to the PHP root. (The system path would be /home/www/site1.com/www
, and that's what chdir
was set to before enabling the chroot
directive).
Here's my relevant http.d/site1.conf file:
<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>
I've turned up the LogLevel in my httpd.d/site.conf file, and here's some of that interesting output:
[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 (*)
Nothing is showing up in the php error log file.
So, after all this,
- Why am I still getting a "File not found" error message?
- Better yet, how do I fix it, or at the very least, how do I better troubleshoot my issue?
This is resolved. There were two issues with my above code.
Issue #1 - Only Apache 2.4.10 and above can support sockets
The default version of Apache that comes in the base CentOS repositories (Apache 2.4.6) only support TCP ports. The above code is therefore incorrect, and the
listen
directive in the php-fpm config file needed to be changed to something like this:I also made the appropriate change in my http.d conf file, but in addition, I also switched to using the
ProxyPassMatch
directive instead of using theFilesMatch
directive. So my code then became:Note that this code is still wrong... see below
Moving on...
Issue #2 - Relevant Paths
The path in the
ProxyPassMatch
directive (or, in the case of my older code using theFilesMatch
directive) inside my http.d conf file becomes relative to the chroot. It is not relative to the www document root (if different).So my code in my http.d conf file became:
And voila! I have a php-fpm chroot.
php-fpm has a bug with chroot and path.
for example with index.php in www
with this config php-fpm write this path :
one solution is to create a symbolic link in shell :
but it is not clean.
https://bugs.php.net/bug.php?id=55322
https://bugs.php.net/bug.php?id=62279
Some people might receive this error because of 2 things.
In case you specify open_basedir, doc_root, user_dir, session.save_path, upload_tmp_dir (and others) in your PHP-FPM.conf, then these paths must be relative to chroot.
For example:
TL;DR just change it to 0.
For some reasons this value affects your PHP-FPM even though this parameter is ment to be for CGI only.
You should read more about this parameter since it may break other things too, more here
Do you have SElinux enabled? getenforce should be able to tell you this. If that's the case, setenforce 0 would disable it and then you'd need to edit /etc/sysconfig/selinux and set SELINUX to disabled so it's persistent after rebooting.