SSH 連線閒置超時自動斷開是常見痛點。解決需同時配置 **伺服端** (ClientAliveInterval) 與 **客戶端** (ServerAliveInterval),並理解 TCPKeepAlive 的網路層差異。本文提供雙端配置、systemd 服務化、tmux 替代方案的完整指南。

| 層級 | 參數 | 配置端 | 機制 | 優點 | 缺點 |
|---|---|---|---|---|---|
| 應用層 (SSH 協定) | ServerAliveInterval |
客戶端 | 定期發送 SSH_MSG_GLOBAL_REQUEST 要求回應 | 穿透 NAT/防火牆、偵測應用層凍結 | 需客戶端配置 |
| 應用層 (SSH 協定) | ClientAliveInterval |
伺服端 | 定期發送 SSH_MSG_CHANNEL_REQUEST 要求回應 | 統一管理所有連線、無需客戶端配合 | 無法偵測客戶端崩潰未發 FIN |
| 傳輸層 (TCP) | TCPKeepAlive |
雙端 (核心) | TCP KEEPALIVE 封包 (預設 2 小時) | 無需應用程式支援、核心自動處理 | 間隔過長、防火牆常丟棄、無法偵測應用層邏輯凍結 |
# 發送保活請求間隔 (秒)
ClientAliveInterval 60
# 最大無回應次數 (60*3=180 秒無回應則斷開)
ClientAliveCountMax 3
# 確保 TCP 層也開啟 (防禦性)
TCPKeepAlive yes
# 重新載入
sudo systemctl reload sshd
Host *
# 每 30 秒發送保活
ServerAliveInterval 30
# 2 次無回應斷開 (30*2=60 秒)
ServerAliveCountMax 2
# 關閉 TCPKeepAlive 避免衝突 (可選)
TCPKeepAlive no
# 自動多路複用 (加速後續連線)
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m
# ~/.config/systemd/user/ssh-tunnel@.service
[Unit]
Description=Persistent SSH Tunnel to %i
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/ssh -N -o ServerAliveInterval=30 -o ServerAliveCountMax=2 %i
Restart=always
RestartSec=10
StandardOutput=journal
[Install]
WantedBy=default.target
# 啟用
systemctl --user enable ssh-tunnel@myserver
systemctl --user start ssh-tunnel@myserver
# 伺服端開啟會話
tmux new -s mysession
# 斷線後重新附著
tmux attach -t mysession
# 系統級自動啟動 (需啟用 linger)
sudo loginctl enable-linger $USER
# ~/.config/systemd/user/tmux@.service 類似上述
ClientAliveInterval 0 (預設關閉),不會主動斷開殭屍連線,佔用資源配置雙端 ServerAliveInterval/ClientAliveInterval 並搭配 tmux,可同時解決「閒置斷開」、「會話丟失」、「殭屍連線佔用」三大痛點。
SVN 中文文件名報錯「Can't convert string from UTF-8」:Locale 配置修復指南
Ubuntu 13.10 VirtualBox 無法啟動解決方案:Kernel Driver 錯誤、DKMS 重編譯、Kernel Headers 安裝
Linux 自動生成 MAC 地址:Shell、Python、Perl、Ruby 四語言實現與效能對比
Linux 閏秒 導致程序回應變慢:偵測與緩解方案 (ntpd slew mode)
Ubuntu 自訂鍵盤快捷鍵啟動應用程式:以 Eclipse 為例
Linux 正則表達式完整參考:基本/擴展語法元字符對照表、grep/egrep/fgrep 三劍客用法詳解