PHP-FPM + nginx 產生權限被拒絕,但僅在某些大頁面上
我有一個 AWS Lightsail 實例(1GB RAM 實例)執行一個相對較新的網站(即幾乎沒有流量)。它正在執行 nginx 和 PHP-FPM 7.3(也嘗試使用 7.2)和 MariaDB。所有這些都在 CentOS 7 下。
在 AWS 免費套餐下一切正常。我執行了一個 T2.micro EC2 實例和一個 T2.micro RDS 實例。Lightsail 有點……更敏感。為了使 Lightsail 正常工作,我將 PHP-FPM 切換到
ondemand
按需 - 啟動時不創建子級。當新請求連接時,孩子將被分叉。
我必須這樣做,否則 MariaDB 會隨機崩潰。這似乎不會影響下面的問題。
Wordpress 管理面板停止正常工作,每個人都說要
CONCATENATE_SCRIPTS
關閉。那行得通……主要是。文章和模板的編輯器都出現故障。沒有人能夠給我一個線索為什麼。環顧四周,我自己發現了一些東西。不工作的頁面沒有完全載入。
CONCATENATE_SCRIPTS
啟用後,CSS 文件將載入到一個巨大的頁面中。因為這無法完全渲染,所以瀏覽器會忽略 CSS 和 JS 文件。CONCATENATE_SCRIPTS
通過簡單地將它們拆分為更小且易於載入的組件文件來解決此問題。但是編輯頁面不能拆分,調試底層問題一直很抓狂。我收到 200 響應和一些數據但是頁面繪製不完整。我會說可能有 80-90% 的 HTML 在那裡,但被切斷了。在從這裡開始的部分(JS 塊)
wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( {"\/":{"body":{"name":"S
它只是突然結束,並且每次都在同一點。就好像 PHP-FPM 或 nginx 剛剛停止,但沒有任何錯誤日誌(關於這種設置的大多數其他問題都是針對根本不繪製的頁面)。更奇怪的是,它不是針對較小的頁面,而是針對非常長的頁面。沒有竊取時間,
top
實例似乎沒有承受任何嚴重的負載,所以我不確定它為什麼會這樣做。我重新載入了所有文件,甚至建立了一個單獨的 WP 站點來測試它,他們都這樣做了。根據評論,我打開了 nginx 調試日誌記錄並發現
2019/08/07 02:33:08 [crit] 1461#0: *47 open() "/var/lib/nginx/tmp/fastcgi/3/00/0000000003" failed (13: Permission denied) while reading upstream, client: x.x.x.x, server: example.com, request: "GET /wp-admin/post-new.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000",
這沒有任何意義,為什麼它會只對少數大文件執行此操作。沒有驅動器已滿或靠近它。我讀了這個問題,但 nginx 和 PHP-FPM 都在
apache
. 刪除 tmp 文件也沒有解決它。這些目錄歸 擁有apache:root
,但將它們更改為apache:apache
無效。SELinux 似乎也不是罪魁禍首。我也不用proxy_cache
。
首先,失敗與FastCGI 緩衝有關,而不是代理記憶體。
這從
/var/lib/nginx/tmp/fastcgi...
.為什麼您只在特別大的頁面上遇到錯誤:如果您配置的 FastCGI 緩衝區不足以將 PHP-FPM 的整個響應放入記憶體中,當然這種情況在大響應時會更頻繁地發生,NGINX 將嘗試寫入部分對臨時文件的響應。
顯然,保存 FastCGI 臨時文件的目錄的權限不允許 NGINX 將文件保存在其中,因此當響應“太大”時,它會在某個點完全失敗。
該路徑
/var/lib/nginx/tmp/fastcgi
還表明您沒有使用官方的 NGINX 發行版,因為如果您使用了,那麼您最終將/var/cache/nginx/fastcgi_temp
擁有nginx:root
.我建議使用股票,官方 NGINX 發行版。
但是 nginx 和 PHP-FPM 都在 apache 下執行
題外話,但是:無論如何,這都是不正確的設置。正確的設置是以一個使用者身份執行 NGINX(無論
apache
是. 然後讓您的使用者成為組的成員。沒有理由僅僅因為您在給定伺服器上只有一個應用程序而在單個使用者下執行所有內容。nginx``foo``nginx``foo
無論哪種方式,將其視為一個典型
chmod
問題:
- 檢查執行的使用者 NGINX 工作程序(
user
配置中的指令)- 嘗試使用該使用者從上到下列出相關目錄的文件,直到找到它停止工作的位置,然後遞歸地修復權限。
例如,假設您的 NGINX 工作程序確實像您所說的那樣由
apache
使用者執行並且它無法訪問/var/lib/nginx/tmp/fastcgi
:sudo -u apache ls /var/
這行得通嗎?權限很好,可以通過NGINX工作程序的使用者遍歷到這個目錄。重要的是要了解您需要能夠遍歷(如
rx
許可)所有上層目錄,以便能夠讀取下面任何目錄的內容。也就是說,對於我們的“最終目的地”,也就是/var/lib/nginx/tmp/fastcgi
,我們需要能夠閱讀所有的/var
,/var/lib
等。如果閱讀
/var
不起作用(儘管會表明某種損壞的系統),您需要讓“其他人”閱讀它,例如chmod o+rX /var
sudo -u apache ls /var/lib
這行得通嗎?/var/lib 的權限很好。如果沒有,您需要讓其他人閱讀它:
chmod o+rX /var/lib
sudo -u apache ls /var/lib/nginx
這行得通嗎?如果沒有,請通過 . 檢查所有權和權限
stat
。然後確保 NGINX 使用者是目錄的所有者,/var/lib/nginx
並且chmod
(這次是“所有者”)允許它遍歷目錄:chown apache:root /var/lib/nginx chmod u+rX /var/lib/nginx
確保相同(由 NGINX 的使用者擁有,可以被它讀取(遍歷))
/var/lib/nginx/tmp
最後,
/var/lib/nginx/tmp/fastcgi
您需要 NGINX 使用者能夠執行所有讀取、執行(遍歷)和寫入操作:chown apache:root /var/lib/nginx/tmp/fastcgi chmod 0700 /var/lib/nginx/tmp/fastcgi
所以基本上它是一個沖洗,重複操作,同時遍歷相關文件,直到它工作。
通過嘗試列出目錄的內容並在其中創建文件來驗證所有設置是否正確:
sudo -u apache ls /var/lib/nginx/tmp/fastcgi sudo -u apache touch /var/lib/nginx/tmp/fastcgi/test.txt