I'm in the process of moving each of my websites that are on a single server from a single PHP instance (whereby all of the files in all websites were owned by apache, and just the default php library was installed without php-fpm) ... and I'm installing a php-fpm pool for each individual website.

Better security and separation of the websites is my goal, the biggest goal being that the PHP scripts in 1 website won't be able to access PHP scripts from another website.

I'm apparently doing something wrong.

My environment:

  • CentOS 7
  • PHP 5.4.16
  • Apache 2.4.6

Here's an example php-fpm pool config file:

[root@host]# cat /etc/php-fpm.d/website1.com.conf 
    user = user1
    group = user1
    listen = /var/run/php-fpm/website1.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
    pm = ondemand
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3
    chdir = /home/www/website1.com/

And here is its corresponding vhost file in Apache:

[root@host]# cat /etc/httpd/conf.d/website1.com.conf 
        <VirtualHost *:80>
                ServerAdmin admin@my-host.com
                ServerName website1.com
        ServerAlias www.website1.com
        DocumentRoot /home/www/website1.com/www
                <Directory "/home/www/website1.com/www">
                        Options Includes FollowSymLinks
                        AllowOverride All
                        Order allow,deny
                        Allow from all
        ErrorLog /home/www/website1.com/logs/errors
        CustomLog /home/www/website1.com/logs/access_log common
                <FilesMatch "\.php$">
                        SetHandler "proxy:unix:///var/run/php-fpm/website1.com.sock|fcgi://website1.com/"


All files and folders are owned solely by user1 (the group is also set to user1).

I have a PHP script inside of "website2" that is still able to access "website1" content. The settings in the php-fpm pool config file for "website2" and the settings in "website2" Apache vhost config file are identical to website 1 (with the exception of different folder paths, home directory, chroot, etc...).

This is my test script, located in /home/www/website2/www/ and accessible via the website2.com domain name:

$test = file_get_contents('/home/www/website1.com/www/wp-config.php');
echo $test;
#$files = scandir('/home/www');

The output of this script is somewhat unexpected, however. I don't see the full contents of wp-config.php. Instead, what I see is everything beyond a certain point in the file (if you're familiar with wp-config.php, I see everything after the define('SECURE_AUTH_KEY','foo') entry).

Why can this test script, which is running under "user2" access and echo out some of the contents of wp-config.php found in the "user1" directory? I thought that the chdir = /home/www/website1.com/ directive would prevent this sort of thing.

  • You may try starting the php-fpm daemon using strace to debug why chroot() is not effective. – Laszlo Valko Oct 31 '15 at 12:03

It appears that you have set chdir instead of chroot in your php-fpm pool configuration.

The chdir directive simply changes the working directory for the php processes for that pool; it does not start the processes in a chroot.

See this question.

  • Also, note that you must remove chdir or set chdir = / once chroot is set. – Joshua Griffiths Oct 31 '15 at 12:16
  • 1
    That seems to have done the trick! ... sort of.... now I'm dealing with a "File not found" error, which others appear to have dealt with too. That's out of scope for this question. Thanks! – David W Oct 31 '15 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.