在實務維運中,SSH 幾乎是所有 Linux 管理工作的基礎。然而,當主機沒有固定 IP、位於 NAT 環境,或基於安全考量不希望對外開放 22 Port 時,Cloudflare Tunnel(cloudflared) 成為一個非常理想的解決方案。
不過,許多人在使用 Cloudflare Tunnel 承載 SSH 時,常會遇到一個問題:
SSH 連線會無預警中斷
本文將從實務角度出發,說明如何透過正確設定,建立一套 可長時間穩定使用的 Cloudflare Tunnel SSH 架構,並同時支援 Host 與內部 Container(Incus / Docker)。
目標與適用情境
本文適合以下情境的使用者:
- 不想對外開放 SSH Port
- 使用 Cloudflare Zero Trust 管理存取
- 主機內有多個內部服務或 Container
- 曾遇過 Cloudflare Tunnel SSH 無預警斷線
- 希望 SSH 連線可用於長時間維運或管理作業
架構概覽:Host 與 Container 共用 Tunnel
本篇教學採用以下設計原則:
- 僅 Host 執行 cloudflared
- Container 不對外暴露
- SSH 流量全程經 Cloudflare Tunnel
- SSH 金鑰驗證仍由系統 sshd 控制
架構角色說明
- Host(DEV-vm)
- 執行
cloudflaredservice - SSH 服務位於
127.0.0.1:22
- 執行
- Container(Incus / HestiaCP)
- 位於內部網段(如
10.10.10.50) - 不需安裝 cloudflared
- SSH 由 Host 轉發
- 位於內部網段(如
Cloudflare Tunnel ingress 設定範例
以下為 Host 上的 config.yml 範例:
ingress:
- hostname: dev-vm.example.org
service: ssh://127.0.0.1:22
- hostname: dev-hcp.example.org
service: ssh://10.10.10.50:22
- service: http_status:404
設計重點說明
- 使用 loopback (
127.0.0.1) 連接 Host 本機 SSH - Container 僅能由 Host 轉發存取
- 最後一條規則防止未匹配流量誤入 Tunnel
為什麼 Cloudflare Tunnel SSH 容易斷線?
Cloudflare Tunnel 本質上是 中介傳輸層,並不保證連線永久存在。當連線長時間沒有任何封包流動時,Cloudflare 可能會將其視為 idle 並回收連線。
這也是許多使用者遇到以下錯誤的原因:
client_loop: send disconnect: Unknown error
Connection closed by remote host
這類錯誤並非 SSH 金鑰或設定錯誤,而是 傳輸通道被中斷。
Client 端(Windows)SSH 穩定性設定
為了避免 Cloudflare 判定連線為 idle,Client 端必須主動送出 keepalive 封包。
以下為 ~/.ssh/config 建議設定(私鑰名稱已隱藏):
Host devvm-ssh-host
HostName dev-vm.example.org
User james
IdentityFile C:\Users\USERNAME\.ssh\YOUR_PRIVATE_KEY
ProxyCommand cloudflared access ssh --hostname %h
GSSAPIAuthentication no
ForwardAgent yes
ServerAliveInterval 30
ServerAliveCountMax 3
Host devvm-ssh-container
HostName dev-hcp.example.org
User annie
IdentityFile C:\Users\USERNAME\.ssh\YOUR_PRIVATE_KEY
ProxyCommand cloudflared access ssh --hostname %h
GSSAPIAuthentication no
ForwardAgent yes
ServerAliveInterval 30
ServerAliveCountMax 3
設定重點
ServerAliveInterval 30:每 30 秒主動送封包ServerAliveCountMax 3:避免短暫抖動立即斷線- 可有效防止 Cloudflare Tunnel idle timeout
Server 端(Host)SSH 補強設定
在 Host 上,同步建議調整 sshd 設定:
ClientAliveInterval 60
ClientAliveCountMax 3
AllowAgentForwarding yes
套用後重新載入 SSH 服務:
sudo systemctl reload ssh
此設定能在 Tunnel 發生短暫 reconnect 時,提高連線存活率。
Container 端的 SSH 安全建議
Container 端建議僅保留必要設定:
PasswordAuthentication no
PubkeyAuthentication yes
Container 不需要知道 Cloudflare Tunnel 的存在,所有安全性仍由 SSH 金鑰機制負責。
常見錯誤觀念釐清
- ❌ Cloudflare Tunnel 不穩定
- ❌ SSH 金鑰設定錯誤
- ❌ Container 架構導致問題
實際上,問題幾乎都來自未設定 keepalive。
總結
Cloudflare Tunnel 非常適合用於 SSH 遠端管理,但前提是:
必須主動處理長連線保活問題
只要在 Client 與 Server 端正確設定 keepalive,Cloudflare Tunnel SSH 完全可以用於正式維運環境,並同時兼顧安全性與便利性。


