Apache-2.4

兩個獨立的 PHP-FPM 站點似乎使用相同的程式碼?

  • November 6, 2016

我有兩個具有兩個程式碼庫的網站,但是當我更改一個程式碼庫時,我看到兩者都發生了變化。

我有同一個網站的兩個結帳。它們被設置為通過 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 程序。

當我在我們的環境中看到類似的問題時,似乎是因為 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參數-預設情況下設置為預設值,如果您在系統上託管多個 PHP 應用程序,則將其設置為預設值可能會導致衝突:true``false

首先,可能在每個典型項目中,您都必須確保將 opcache.use_cwd 選項設置為 true。啟用此設置意味著 OpCache 引擎將查看完整的文件路徑以區分具有相同名稱的文件。將其設置為 false 將導致具有相同基本名稱的文件之間發生衝突。

  1. 如果您正在執行由 Zend Framework 或其他使用註釋的類似框架提供支持的應用程序,您還需要確保opcache.load_commentsandopcache.save_comments指令設置為true. 您應該在您的應用程序/框架文件中仔細檢查此建議,因為大多數人現在已經更新了他們的文件,其中包含有關為他們的系統正確使用 OpCache 的具體說明:

在使用註釋的工具和框架中,還有一個設置很重要。如果您使用 Doctrine、Zend Framework 2 或 PHP 單元,請記住將 opcache.load_comments 和 opcache.save_comments 設置設置為 true。因此,您文件中的文件註釋也將包含在 OpCache 生成的預編譯程式碼中。此設置將允許您使用註釋而不會受到任何干擾。

如果您的項目基於特定框架或 Web 應用程序,最好查看文件以了解有關 OpCache 配置的任何指南

重要筆記


希望這會有所幫助 - 如果您使用的是 cPanel,請發表評論,讓我們知道您是如何處理這部分配置的!

引用自:https://serverfault.com/questions/705304