Search code examples
phpphp-7lxdfpm

Why is my PHP7.0-FPM pool not running using it's specified system user?


I've done this setup quite often but this time I'm overseeing something surely.

Goal

Having an Apache 2.4 vhosts using different PHP-FPM pools for each vhost using their own system user within an LXD container.

The problem

Everything is working fine except that when a file is uploaded, the upload directory must be set on www-data which shouldn't be needed in PHP-FPM.

System

Ubuntu 16.04 LXD contianer

Code

/etc/apache2/conf-enabled/php7.0-fpm.conf

root@web1:~# cat /etc/apache2/conf-enabled/php7.0-fpm.conf 
# Redirect to local php-fpm if mod_php is not available
<IfModule !mod_php7.c>
    # Enable http authorization headers
    SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1

    <FilesMatch ".+\.ph(p[3457]?|t|tml)$">
        SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
    </FilesMatch>
    <FilesMatch ".+\.phps$">
        # Deny access to raw php sources by default
        # To re-enable it's recommended to enable access to the files
        # only in specific virtual host or directory
        Require all denied
    </FilesMatch>
    # Deny access to files without filename (e.g. '.php')
    <FilesMatch "^\.ph(p[3457]?|t|tml|ps)$">
        Require all denied
    </FilesMatch>
</IfModule>

/etc/apache2/sites-enabled/hs2.nl.conf

root@web1:~# cat /etc/apache2/sites-enabled/hs2.nl.conf 
<VirtualHost *:80>
  ServerAdmin webmaster@hs2.nl
  ServerName hs2.nl
  ServerAlias www.hs2.nl
  DocumentRoot /var/www/html/hs2.nl/web
  ErrorLog ${APACHE_LOG_DIR}/hs2.nl-error.log
  CustomLog ${APACHE_LOG_DIR}/hs2.nl-access.log combined
  #LogFormat "%h %l %u %t \"%r\" %>s %b %{X-Forwarded-For}i" common
  <Directory /var/www/html/hs2.nl/web>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
  </Directory>
  <Directory /usr/lib/cgi-bin>
    Require all granted
  </Directory>
  <IfModule mod_fastcgi.c>
    AddHandler php7-fcgi .php
    Action php7-fcgi /php7-fcgi
    Alias /php7-fcgi /usr/lib/cgi-bin/hs2.nl-fcgi
    FastCgiExternalServer /usr/lib/cgi-bin/hs2.nl-fcgi -socket /var/run/php/hs2.nl-fpm.sock -pass-header Authorization
  </IfModule>
</VirtualHost>

/etc/php/7.0/fpm/pool.d/hs2.nl.conf

root@web1:~# cat /etc/php/7.0/fpm/pool.d/hs2.nl.conf 
[hs2.nl]
user = hs2.nl
group = hs2.nl
listen = /var/run/php/hs2.nl-fpm.sock
listen.owner = hs2.nl
listen.group = hs2.nl
prefix = /var/www/html/hs2.nl
chroot = $prefix
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Directory permissions

hs2.nl@web1:~/web/uploads$ ls -ald .
drwxr-xr-x 2 hs2.nl hs2.nl 2 Oct 26 15:15 .
hs2.nl@web1:~/web/uploads$ pwd
/var/www/html/hs2.nl/web/uploads

Processes running as their respective user

root@web1:~# ps aux | egrep "USER|php-fpm: master|pool hs2.nl"
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     16470  0.0  0.3 365880 20220 ?        Ss   14:55   0:00 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
hs2.nl   16479  0.0  0.0 365688  4764 ?        S    14:55   0:00 php-fpm: pool hs2.nl
hs2.nl   16480  0.0  0.0 365688  4764 ?        S    14:55   0:00 php-fpm: pool hs2.nl

phpinfo

hs2.nl@web1:~/web$ cat phpinfo.php 
<?php
$id = shell_exec(id);
$whoami = shell_exec(whoami);
echo "Id: " . $id . "<br />";
echo "Who am I?: " . $whoami . "<br />";
phpinfo();
?>

Output

Id: uid=33(www-data) gid=33(www-data) groups=33(www-data) 
Who am I?: www-data 

Further thoughts

I thought it might have something to do with LXD but as it seems all pools run under their own users.

Edit: to eliminate this theory I've loaded the very same configuration onto a normal KVM virtual machine where I was able to reproduce the problem in exactly the same way so I must've done something wrong in my configuration, it's nothing to do with LXD.


Solution

  • Found the answer in Koen Reiniers' blog: http://blog.koenreiniers.nl/guide-to-combining-apache-virtual-hosts-and-php7-fpm/

    Basically my fault was to have a single 'Handler' for multiple vhosts PHP-FPM sockets.

    I changed my vhost config to:

    <IfModule mod_fastcgi.c>
      AddHandler php7-fcgi-hs2.nl .php
      Action php7-fcgi-hs2.nl /php7-fcgi-hs2.nl
      Alias /php7-fcgi-hs2.nl /usr/lib/cgi-bin/php7-fcgi-hs2.nl
      FastCgiExternalServer /usr/lib/cgi-bin/php7-fcgi-hs2.nl -socket /run/php/php7.0-fpm.hs2.nl.sock -pass-header Authorization
      <Directory "/usr/lib/cgi-bin">
      Require all granted
      </Directory>
    </IfModule>
    <VirtualHost *:80>
      ServerAdmin webmaster@hs2.nl
      ServerName hs2.nl
      ServerAlias www.hs2.nl
      DocumentRoot /var/www/html/hs2.nl/web
      ErrorLog ${APACHE_LOG_DIR}/hs2.nl-error.log
      CustomLog ${APACHE_LOG_DIR}/hs2.nl-access.log combined
      #LogFormat "%h %l %u %t \"%r\" %>s %b %{X-Forwarded-For}i" common
      <Directory /var/www/html/hs2.nl/web>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
      </Directory>
      <IfModule mod_fastcgi.c>
          <FilesMatch ".+\.ph(p[345]?|t|tml)$">
              SetHandler php7-fcgi-hs2.nl
          </FilesMatch>
      </IfModule>
    </VirtualHost>

    And in my PHP-FPM pool I added listen.mode = 0666:

    [hs2.nl]
    user = hs2.nl
    group = hs2.nl
    listen = /run/php/php7.0-fpm.hs2.nl.sock
    listen.owner = hs2.nl
    listen.group = hs2.nl
    listen.mode = 0666
    ;prefix = /var/www/html/hs2.nl
    ;chroot = $prefix
    pm = dynamic
    pm.max_children = 5
    pm.start_servers = 2
    pm.min_spare_servers = 1
    pm.max_spare_servers = 3