好吧,這太蠢了。我在 Ubuntu 16.04 伺服器實例上執行 Apache 2.4。我對生產和測試實例幾乎使用相同的環境,以及使用 Vagrant 進行開發管理的幾乎相同的 VirtualBox 實例。在最長的時間裡,我能夠以運行 Apache 的相同用戶身份透過 SSH 連接到這些伺服器實例,部署一些應用程式程式碼更改,然後運行exit
以終止 SSH 會話,之後 Apache 就會正常運行。但是現在,如果exit
Apache 服務沒有遇到致命錯誤,我就無法執行此操作:
[mpm_prefork:emerg] [pid 23466] (43)Identifier removed: AH00144: couldn't grab the accept mutex
[core:alert] [pid 17750] AH00050: Child 23466 returned a Fatal error... Apache is exiting!
筆記:
- Apache 使用者是
app
. - 如果我 SSH 作為
app
,切換到root
,restart
服務作為root
,切換回app
,然後終止會話,它會殺死 Apache。 - 如果我透過 SSH 作為
root
服務restart
,然後終止會話,Apache 就可以了。 - 如果我 SSH 作為
root
服務restart
,切換到app
,切換回root
,然後終止會話,Apache 就可以了。 - 如果我 SSH 作為
root
服務restart
,終止會話,再次 SSH 作為app
,然後再次終止會話,它會殺死 Apache。 - 在本週之前,我已經能夠始終如一地通過 SSH as
app
、切換到root
、restart
服務 asroot
,並終止會話,而無需終止 Apache。 - 我嘗試修改
/lib/systemd/system/apache2.service.d/apache2-systemd.conf
該行並將其更改RemainAfterExit=no
為RemainAfterExit=yes
,執行 asystemctl daemon-reload
,最後執行 a ,但service apache2 restart
沒有效果。
對於行為的突然改變有什麼解釋嗎?是否有合理的修復來恢復以前的行為?如果不是,那麼部署對應用程式程式碼的變更並授予 Apache(使用者app
)無需登入 SSH 會話即可讀取它的權限的最佳實踐是什麼root
?登入 as 的全部原因就是為了限制app
登入 as 的需要。root
我在這裡完全不知所措,不明白一切怎麼會突然被打破。
答案1
根本原因是 systemd(從 219 開始)處理登入使用者建立的 IPC 物件的方式發生了變化。預設情況下,它將刪除使用者登出後留下的所有 IPC 物件。這適用於所有非系統使用者(uid >= 1000)。系統使用者(uid < 1000)不受影響。
由於您已將 Apache 變更為在非系統使用者下運行,因此每當您登出該使用者帳戶時,systemd 都會對 Apache 的所有 IPC 物件進行核攻擊,然後 Apache 會抱怨丟失其互斥體並死亡。
您可以透過設定RemoveIPC=no
(/etc/systemd/logind.conf
Ubuntu 上的預設設定是yes
)並重新啟動來更改此行為systemd-logind.service
。
最好讓 Apache 以系統使用者身分執行(例如www-data
在 Ubuntu 上),並使用權限和 ACL 來授予www-data
對其需要讀取/寫入的檔案的存取權限。