What is the correct way to set up Apache virtualhosts and PHP-FPM pools with different users, one user per project, so that
- each user/project is independent from each other in file access
- projects using normal Apache /
www-data
, can not access the pooled projects?
I have a set up where I'm using Apache with virtualhosts, and I want to set up each virtualhost with their own php-fpm
pool:
- Apache virtualhost
site1.conf
:
<VirtualHost *:443>
DocumentRoot /var/www/site1/public
<Directory /var/www/site1/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
# 2.4.10+ can proxy to unix socket
SetHandler "proxy:unix:/run/php/php-fpm.site1.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>
- PHP pool for
site1
:
[site1]
user = site1
group = site1
listen.owner = site1
listen.group = www-data
listen.mode = 0660
- The directory starting at
/var/www/site1
:
drwxr-xr-x 15 site1 site1 4,0K ago 31 11:48 .
drwxr-xr-x 15 site1 site1 4,0K ago 31 11:48 public
- And the user:
id site1
uid=1007(site1) gid=1007(site1) grupos=1007(site1),33(www-data)
Ditto other configuration files for virtualhost site2
, changing where adequate.
Now, this configuration works and all files are served, but it's too open for what it's intended.
For starters, the files and directories in the public area of site1
have to be served with world-readable permission (eg.: rwxr--r-- site1 site1 file
). If I make the file readable only for site1 as it should be, I get HTTP 403
and EACCESS
errors everywhere. I understand that at some point Apache has to have access to the files, but I thought the entire purpose of a FPM pool was to take care of that access.
This also means that, unless project users set up their umask
adequately, new files they create might not have the adequate permissions and they must be made world-readable by hand before the webserver (or FPM?) can access them.
I thought that one potential solution would be to make www-data
user, which runs Apache, a member of site1
(site2
, etc...), but that would give other projects running on Apache full access to the project files anyway, including non-front facing elements such as Laravel config, backend connectors, etc. So in theory this doesn't work,
A second option would be to set up each project's public
directory with either www-data
setgid
or with a read directive for ẁww-data
via ACL (setfacl
) to make them readable by Apache's user specifically, but I'm not sure if that's doable without first giving Apache full path access to read the project, since in Linux a directory path is only readable if all its parent paths are. It could work, but I'm not entirely sure what is the corresponding setup.
The only other option I could see would be to set up Apache itself so that the different virtualhosts are run with their own users, but I've found no usable documentation about such setups. The closest I've found is something called apache2-mpm-itk
which advertises this capability, but I've found no usable configuration that actually lets an Apache service start while this module is enabled. In fact, the default configuration for itk in a Debian 9 machine right out segfaults Apache once started.
What am I missing here to achieve the correct configuration? I take it it has to be possible, at least I assume that's how any normal web hoster does it.