masterdam79 masterdam79 - 1 month ago 18
PHP Question

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.

Answer

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