两个独立的 PHP-FPM 站点似乎使用相同的代码?

San*_*hal 4 cache fastcgi php-fpm opcode apache-2.4

我有两个带有两个代码库的网站,但是当我更改一个代码库时,我会看到两者都发生了变化。

我有两个同一个网站的结帐。它们被设置为通过带有 FastCGI 的 Apache2 使用 PHP-FPM。结帐在:

/var/www/site1
/var/www/site2
Run Code Online (Sandbox Code Playgroud)

Apache 配置如下所示:

<VirtualHost *:80>
    ServerName site1.myserver.com
    DocumentRoot /var/www/site1
    <IfModule mod_fastcgi.c>
        AddHandler php5-fcgi-handler .php
        Action php5-fcgi-handler /php5-fcgi-uri
        Alias /php5-fcgi-uri fcgi-application
        FastCgiExternalServer fcgi-application -socket /var/run/site1-fpm.sock -pass-header Authorization -idle-timeout 30000 -flush
    </IfModule>
</VirtualHost>

<VirtualHost *:80>
    ServerName site2.myserver.com
    DocumentRoot /var/www/site2
    <IfModule mod_fastcgi.c>
        AddHandler php5-fcgi-handler .php
        Action php5-fcgi-handler /php5-fcgi-uri
        Alias /php5-fcgi-uri fcgi-application
        FastCgiExternalServer fcgi-application -socket /var/run/site2-fpm.sock -pass-header Authorization -idle-timeout 30000 -flush
    </IfModule>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

FPM 池配置如下所示:

[site1]
user = site1-user
group = site1-group
listen = /var/run/site1-fpm.sock
listen.owner = www-data
listen.group = www-data
chdir = /
pm = ondemand
pm.max_children = 5
pm.max_requests = 500 ;default to unlimited

[site2]
user = site2-user
group = site2-group
listen = /var/run/site2-fpm.sock
listen.owner = www-data
listen.group = www-data
chdir = /
pm = ondemand
pm.max_children = 5
pm.max_requests = 500 ;default to unlimited
Run Code Online (Sandbox Code Playgroud)

我没有使用 FPM 的 chroot 功能(据我所知)。

当我更改 site1 的代码并重新启动 PHP-FPM 并访问 site1 和 site2 时,我会在两个站点上看到更改。

如果我重新启动 PHP-FPM 并首先访问 site2(未更改的站点),然后访问 site1,那么我在任何一个站点上都看不到更改。

我的配置有什么问题?我确实看到在主 FPM 主机下为 site1 和 site2 运行单独的 PHP-FPM 进程。

Bry*_*Jr. 13

当我在我们的环境中看到类似问题时,似乎是因为 OpCache(默认情况下)在共享托管环境中的所有用户之间共享单个缓存的方式。已经提交了一个错误(并且您可以并且应该去投票让维护者知道这对您的用例可能有多重要),尽管没有承诺提供修复程序。

TL;DR :默认情况下,启用 OpCache 时,用于存储已编译字节码的缓存在所有用户之间共享。在托管在多个站点/用户之间共享的环境中,这可能导致站点从另一个站点抓取 php 脚本的缓存输出,或者,如果启用了特定的安全设置,甚至会产生错误

如果您计划将 PHP-FPM 与 PHP 5.5+ 的内置 opcache 一起使用,请在实际操作之前阅读下面的博客文章。事实证明,服务器上的任何用户都可以读取操作码缓存。这意味着,如果有 10 个独立的用户,拥有自己的虚拟主机和目录,并且您为每个用户配置一个 PHP-FPM 池,每个用户仍然可以看到缓存了哪些脚本及其位置。由于他们对缓存具有读访问权限,因此他们可能会查看所有这些数据。

这显然是一个巨大的安全问题,即使没有人利用这一点,在生成页面时仍有可能被错误的用户读取脚本,因此如果有多个索引,网站可能会显示错误的数据/信息缓存中的 .php 脚本。

虽然没有正式发布修复程序,但如果您使用的是 cPanel,这个 wiki 有一个文档化的方式来配置要在每个用户的基础上创建和保护的 php-fpm 池,如果您按照下面的说明以及此答案底部的重要说明您应该能够获得所需的功能而不会出现任何错误

该帖子还记录了如何在每个站点/每个用户的基础上手动配置它(尽管我敢打赌,如果您托管了很多站点,这可能会变得乏味)。如果您不使用 cPanel,您可能需要修改脚本以指定您的个人路径和用户名,而不是 cPanel 配置引擎使用的变量。


重要笔记

在测试和其他研究期间,我看到了这篇文章,其中提供了一些可能与您的具体情况相关的说明:

  1. 您需要确保为您的应用程序的 OpCache 配置opcache.use_cwd设置该参数true-false默认情况下设置为,如果您在系统上托管多个 PHP 应用程序,将其设置为默认值可能会导致冲突:

首先,可能在每个典型项目中,您都必须确保 opcache.use_cwd 选项设置为 true。启用此设置意味着 OpCache 引擎将查看完整文件路径以区分具有相同名称的文件。将其设置为 false 将导致具有相同基本名称的文件之间发生冲突。

  1. 如果您正在运行由 Zend Framework 或其他使用注释的类似框架提供支持的应用程序,您还需要确保将opcache.load_commentsopcache.save_comments指令设置为true。你应该用你的应用程序/框架文档仔细检查这个建议,因为大多数人现在已经更新了他们的文档,其中包含有关为他们的系统正确使用 OpCache 的具体说明:

在使用注释的工具和框架中,还有一个很重要的设置。如果您使用 Doctrine、Zend Framework 2 或 PHP Unit,请记住将 opcache.load_comments 和 opcache.save_comments 设置设置为 true。因此,您的文件中的文档注释也将包含在 OpCache 生成的预编译代码中。此设置将允许您在没有任何中断的情况下使用注释。

如果您的项目基于特定框架或 Web 应用程序,检查文档以获取有关 OpCache 配置的任何指南总是一个好主意

重要笔记


希望这会有所帮助 - 如果您使用的是 cPanel,请发表评论让我们知道您是如何处理该部分配置的!