![两个独立的 PHP-FPM 站点似乎使用相同的代码?](https://linux22.com/image/662330/%E4%B8%A4%E4%B8%AA%E7%8B%AC%E7%AB%8B%E7%9A%84%20PHP-FPM%20%E7%AB%99%E7%82%B9%E4%BC%BC%E4%B9%8E%E4%BD%BF%E7%94%A8%E7%9B%B8%E5%90%8C%E7%9A%84%E4%BB%A3%E7%A0%81%EF%BC%9F.png)
我有两个网站和两个代码库,但是当我更改一个代码库时,我会看到两个代码库都发生变化。
我有同一个网站的两个结帐。它们设置为通过 Apache2 和 FastCGI 使用 PHP-FPM。结帐位于:
/var/www/site1
/var/www/site2
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>
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
我没有使用 FPM 的 chroot 功能(据我所知)。
当我更改 site1 的代码并重新启动 PHP-FPM 并访问 site1 和 site2 时,我会看到两个站点上的变化。
如果我重新启动 PHP-FPM 并首先访问 site2(未更改的站点),然后访问 site1,那么我不会在任何一个站点上看到更改。
我的配置有什么问题?我确实看到在主 FPM 主机下为 site1 和 site2 运行单独的 PHP-FPM 进程。
答案1
当我在我们的环境中看到类似的问题时,似乎是因为 OpCache(默认情况下)在共享托管环境中为所有用户共享单个缓存的方式造成的。错误已提交(并且您可以并且应该去投票,让维护人员知道这对您的用例有多重要)尽管尚未承诺提供修复。
TL;DR:默认情况下,当启用 OpCache 时,用于存储已编译字节码的缓存在所有用户之间共享。在多个站点/用户共享托管的环境中,这可能会导致一个网站从另一个网站获取 php 脚本的缓存输出,或者,如果启用了特定的安全设置,甚至会产生错误。
如果您计划将 PHP-FPM 与 PHP 5.5+ 内置的 opcache 结合使用,请在实际操作之前阅读下面的博客文章。事实证明,服务器上的任何用户都可以读取操作码缓存。这意味着,如果有 10 个独立的用户,他们有自己的虚拟主机和目录,并且您为每个用户配置一个 PHP-FPM 池,则每个用户仍然可以看到缓存了哪些脚本及其位置。由于他们具有对缓存的读取权限,因此他们可能会查看所有这些数据。
这显然是一个巨大的安全隐患,即使没有人利用这一点,在生成页面时仍有可能由错误的用户读取脚本,因此如果缓存中有多个 index.php 脚本,网站可能会显示错误的数据/信息。
虽然官方尚未发布修复程序,但如果你正在使用 cPanel,此 wiki 记录了如何配置 php-fpm 池以根据每个用户进行创建和保护如果你遵循以下说明以及重要笔记在这个答案的底部,你应该能够获得你想要的功能而不会出现任何错误
该帖子还记录了如何根据每个站点/每个用户手动配置这一点(不过我敢打赌,如果您托管很多站点,这可能会变得很乏味)。如果您不使用 cPanel,您可能需要修改脚本以指定您的个人路径和用户名,而不是 cPanel 的配置引擎使用的变量。
重要笔记
在测试和进一步研究期间我遇到了这篇文章提供了一些澄清这可能与您的具体情况相关:
- 您需要确保将应用程序的 OpCache 配置的
opcache.use_cwd
参数设置为true
- 默认情况下设置为false
,如果您的系统上托管多个 PHP 应用程序,则将其设置为默认值可能会导致冲突:
首先,可能在每个典型项目中,您都必须确保 opcache.use_cwd 选项设置为 true。启用此设置意味着 OpCache 引擎将查看完整文件路径以区分具有相同名称的文件。将其设置为 false 将导致具有相同基本名称的文件之间发生冲突。
- 如果你正在运行由 Zend Framework 或其他使用注释的类似框架提供支持的应用程序,则还需要确保将
opcache.load_comments
和opcache.save_comments
指令设置为true
。你应该使用你的应用程序/框架文档仔细检查此建议,因为大多数文档现在都已更新了其文档,其中包含有关在其系统中正确启用 OpCache 的具体说明:
在使用注释的工具和框架中,还有一个设置也很重要。如果您使用 Doctrine、Zend Framework 2 或 PHP Unit,请记住将 opcache.load_comments 和 opcache.save_comments 设置设置为 true。这样,文件中的文档注释也将包含在 OpCache 生成的预编译代码中。此设置将允许您使用注释而不会受到任何干扰。
如果你的项目基于特定的框架或 Web 应用程序,最好检查文档中是否有关于 OpCache 配置的指南
重要笔记
希望这会有所帮助 - 如果您使用 cPanel,请发表评论让我们知道您如何处理这部分配置!