Apache + php-fpm:每个池、每个用户项目的适当权限?

Apache + php-fpm:每个池、每个用户项目的适当权限?

使用不同用户(每个项目一个用户)设置 Apache 虚拟主机和 PHP-FPM 池的正确方法是什么?

  • 每个用户/项目在文件访问方面彼此独立
  • 使用普通 Apache / 的项目www-data,无法访问池化项目?

我有一个将 Apache 与虚拟主机一起使用的设置,并且我想为每个虚拟主机设置自己的php-fpm池:

  • 阿帕奇虚拟主机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 池site1
[site1]
user = site1
group = site1
listen.owner = site1
listen.group = www-data
listen.mode = 0660

  • 目录起始于/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

  • 和用户:
id site1
uid=1007(site1) gid=1007(site1) grupos=1007(site1),33(www-data)

同上 virtualhost 的其他配置文件site2,在适当的地方进行更改。


现在,此配置有效并且所有文件均已提供,但它对于其预期目的来说过于开放。

对于初学者来说,公共区域中的文件和目录site1必须使用世界可读许可(例如:rwxr--r-- site1 site1 file)。如果我将文件设置为仅对 site1 可读,则到处都会出现HTTP 403错误EACCESS。我知道 Apache 在某些时候必须有权访问这些文件,但我认为 FPM 池的全部目的就是处理该访问。

这也意味着,除非项目用户进行了充分的设置umask,否则他们创建的新文件可能没有足够的权限,并且必须先将它们手动设置为全局可读,然后网络服务器(或 FPM?)才能访问它们。

我认为一个潜在的解决方案是让运行 Apache 的用户成为(等...)www-data的成员,但这将使在 Apache 上运行的其他项目能够完全访问项目文件,包括非前端元素比如 Laravel 配置、后端连接器等。所以理论上这是行不通的,site1site2

第二个选项是使用或通过 ACL ( )的读取指令设置每个项目的public目录,以使 Apache 用户可以专门读取它们,但我不确定如果不首先授予 Apache 读取的完整路径访问权限,这是否可行项目,因为在 Linux 中目录路径只有在以下情况下才可读www-data setgidẁww-datasetfacl全部它的父路径是。它可以工作,但我不完全确定相应的设置是什么。

我能看到的唯一其他选择是设置 Apache 本身,以便不同的虚拟主机由自己的用户运行,但我没有找到有关此类设置的可用文档。我发现的最接近的是名为 的东西,apache2-mpm-itk它宣传了此功能,但我没有发现任何可用的配置实际上可以让 Apache 服务开始当该模块启用时。事实上,Debian 9 机器中 itk 的默认配置一旦启动就会出现段错误。

为了实现正确的配置,我缺少什么?我接受它这是可能的,至少我认为任何普通的网络托管服务商都是这样做的。

答案1

我最近设置了类似的配置,只是出于性能原因允许 Apache 全局读取。我使用 mpm_event_module。

您必须考虑到 Apache 和 PHP-FPM 是两个独立的进程。这两者具有独立的设置和环境,并且不会相互影响,因为 PHP-FPM 照顾 Apache 的权限。

当您以老式方式使用表单上传文件时,Apache 需要读取静态文件或写入权限。如果您通过 PHP 代码上传文件,则 PHP-FPM 启动。PHP-FPM 仅处理 PHP 代码。

listen.owner = site1
listen.group = www-data
listen.mode = 0660

用于 Apache 进程,因此它可以将 .php 文件传递​​(写入)到 PHP-FPM unix 套接字。

user = site1
group = site1

池中是运行 PHP 代码的真实用户/组。用户site1 一定不位于www-data组中,因为攻击可以site1在具有组权限的其他虚拟主机目录上进行写入www-data

您的问题的解决方案是 apache-mpm-itk。

如果您让 Apache 全局读取,那么您可以使用任何 MPM(多处理模块)。 apache-mpm-itk 与线程 MPM 不兼容。唯一的选项是 mpm_prefork_module。尽管它的名称是 apache-mpm-itk,但从技术上讲它并不是 MPM。这是一个改进的预叉。

不要忘记在 PHP-FPM 中为每个池设置 open_basedir 指令。

我推荐 2020 年的 Debian 10(buster)。

相关内容