與 ssh 斷開連接時 tmux 會話被終止
摘要:我試圖弄清楚為什麼當我從 ssh 斷開連接時我的 tmux 會話會死掉
詳情:
我在 Arch Linux 系統上安裝了 tmux。當我啟動一個 tmux 會話時,我可以從中分離,然後在 ssh 會話處於活動狀態時再次附加。但是如果我結束我的 ssh 會話,那麼 tmux 會話就會被終止。
我知道這不是正常行為,因為我有其他系統,即使 ssh 會話結束,tmux 會話也會繼續執行,並且我可以在建立新的 ssh 連接後附加到 tmux 會話。有問題的系統和正常工作的系統具有非常相似的配置,所以我不確定要檢查什麼。
我正在執行 tmux 1.9a 版。有問題的系統(我有 root 訪問權限)的 Linux 核心版本為 3.17.4-1,正常工作的系統的核心版本為 3.16.4-1-ARCH(我沒有 root 權限)系統)。我懷疑核心版本是問題的根源,這只是我注意到的一個區別。
我想我會問是否有人見過類似的問題並知道可能的解決方案。
導致問題的確切步驟是:
- ssh 到機器
- 執行
tmux
以啟動 tmuxctrl-B D
分離(此時我可以重新連接tmux attach
- 關閉 ssh 會話(此時 tmux 會話被終止,當我在另一個終端以 root 身份登錄時,我已經能夠觀察到這一點)
- 重新連接 ssh 並執行
tmux attach
,我收到消息no sessions
並執行tmux ls
返回failed to connect to server: Connection refused
。這是有道理的,因為服務沒有執行。對我來說沒有意義的是為什麼當我從 ssh 會話斷開連接時它在第 4 步中被殺死。數據失去:
作為對其中一條評論的回應,我使用 strace 來查看系統呼叫 tmux 伺服器程序所做的事情。看起來當我退出我的 ssh 會話(通過鍵入
exit
或 withctrl-d
)時,tmux 程序被殺死了。這是 strace 輸出的最後一部分的片段。poll([{fd=4, events=POLLIN}, {fd=11, events=POLLIN}, {fd=6, events=POLLIN}], 3, 424) = ? ERESTART_RESTARTBLOCK (Interrupted by signal) --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=1, si_uid=0} --- sendto(3, "\17", 1, 0, NULL, 0) = 1 +++ killed by SIGKILL +++
我將其與 tmux 正常工作的不同系統進行了比較,在該系統上,即使在我退出後,tmux 程序也會繼續執行。所以根本原因似乎是當我關閉 ssh 會話時 tmux 程序正在終止。我需要花一些時間來解決這個問題以找出原因,但我想我會更新我的問題,因為 strace 建議很有用。
理論
包括 systemd 在內的一些 init 系統提供了殺死屬於該服務的所有程序的功能。該服務通常啟動一個程序,該程序通過分叉創建更多程序,這些程序也可以這樣做。所有此類過程通常都被視為服務的一部分。在 systemd 中,這是使用cgroups完成的。
在 systemd 中,預設情況下,當服務停止時,屬於服務的所有程序都會被殺死。SSH 伺服器顯然是服務的一部分。當您連接到伺服器時,SSH 伺服器通常會分叉,新程序會處理您的 SSH 會話。通過從 SSH 會話程序或其子程序分叉,其他伺服器端程序將啟動,包括您的screen或tmux。
Killmode 和套接字啟動
可以使用該
KillMode
指令更改預設行為。上游項目不 AFAIK 包含任何.service
文件,因此這些文件因分佈而異。通常有兩種方法可以在您的系統上啟用 SSH。ssh.service
一個是在網路上維護一個長時間執行的 SSH 守護程序的經典之作。另一種是通過套接字啟動處理,ssh.socket
然後啟動sshd@.service
它只執行一個單一的 SSH 會話。解決方案
如果您的程序在會話結束時被終止,則可能是您正在使用套接字啟動,並且當 systemd 注意到 SSH 會話程序退出時,它會被 systemd 終止。在這種情況下,有兩種解決方案。
ssh.service
一種是通過使用而不是來避免使用套接字啟動ssh.socket
。另一種是設置KillMode=process
在Service
.ssh@.service
該
KillMode=process
設置也可能對 classic 有用ssh.service
,因為它可以避免在伺服器停止或重新啟動時殺死 SSH 會話程序或screen或tmux程序。未來筆記
這個答案顯然獲得了一定程度的普及。雖然它適用於 OP,但由於systemd-logind 開發或配置,它可能會在未來不適用於某人。如果您遇到與此答案中描述不同的行為,請查看有關登錄會話的文件。