你剛開好一台 Linux VPS,或是凌晨兩點監控告警說 SSH 登不進去。終端機跳出一行 ssh: connect to host … port 22: Connection refused,心跳立刻加快。更糟的是:手邊沒有 VNC、沒有雲端主控台,只能對著閃爍游標發呆。
這類問題我們每個月都會遇到幾次——有時是新人改完 sshd_config 忘了 reload,有時是安全群組只開了 80/443 卻漏了 22,還有時是 fail2ban 把你家寬頻的 IP 悄悄封了。好消息是:SSH 連線被拒通常有跡可循,不需要靠玄學。本文把實戰裡最高頻的五條排查路徑整理成清單,按「先讀報錯、再分層」的順序走,大多數情況二十分鐘內能定位根因。
前提說明:下文假設你還有某種備用登入管道——雲端 VNC、序列埠主控台,或同一 VPC 內的另一台機器。若完全失聯,請直接跳到 徹底被鎖在外面時怎麼辦。
排障前必做:三種「連不上」不是一回事
很多人把 Connection refused、Connection timed out 和 Permission denied 混為一談,排查方向就完全偏了。根據 OpenSSH 官方文件,這三者分別指向堆疊的不同層級:
| 報錯關鍵字 | 通常代表什麼 | 優先檢查 |
|---|---|---|
Connection refused |
TCP 已到達主機,但該埠沒有程序在監聽,或本機防火牆回了 REJECT | sshd 是否在跑?監聽埠正確嗎?本機 ufw/iptables? |
Connection timed out |
封包在路徑中被丟棄(路由、雲端安全群組、上游防火牆) | 安全群組、公網 IP 是否正確、ICMP/埠探測 |
Permission denied |
SSH 握手成功,但認證失敗(金鑰、密碼、使用者政策) | 金鑰權限、AllowUsers、fail2ban 是否封了你的 IP |
-v 看細節ssh -v user@host(需要時可疊到 -vvv),觀察卡在「Connecting」還是「Authenticating」。前者是網路或埠的問題,後者才是金鑰與使用者設定。
先把這個區分搞清楚,能省下不少時間。Connection refused 代表封包已經到了——問題在伺服器端或緊鄰的網路邊界。Timed out 代表中間某處把流量吞掉了,在連不上的機器上盯著 sshd_config 改也沒用,得先打通路徑。Permission denied 幾乎都是憑證、帳號政策,或 TCP 連線建立後的 IP 封鎖。
若是團隊協作,請把完整報錯字串貼到事件頻道。「SSH 掛了」會引來十二種猜測;「辦公室 IP 連 2222 埠出現 Connection refused」則能立刻縮小搜尋範圍。
方法一:確認 IP、DNS 與埠可達性(網路層)
在懷疑 sshd 之前,先證明路是通的。新購 VPS 最常見的狀況是:IP 打錯、DNS 還沒生效,或 sshd 監聽在非預設埠而你仍用 22 連線。
請在本機依序執行:
# 1. Confirm resolved IP is correct dig +short your.domain.com ping -c 3 your.server.ip # 2. Probe whether SSH port is open (replace 22 with your actual port) nc -zv your.server.ip 22 # or telnet your.server.ip 22 # 3. Connect with explicit port (avoids ~/.ssh/config surprises) ssh -p 22 -i ~/.ssh/id_ed25519 user@your.server.ip
若 nc 回傳 Connection refused,封包已到伺服器——問題在本機服務或本機防火牆,繼續方法二。若出現 timed out 或探測一直卡住,優先查雲端安全群組 / Network ACL:入站規則是否放行 TCP 22(或你的自訂埠)?來源是 0.0.0.0/0,還是誤設成只有某個內網段?
也別忘了檢查自己的網路。公司 VPN、校園網、部分 ISP 會過濾 22 埠。暫時把 sshd 改到 443 或 2222 做對照測試是經典手法:若換埠能連上,根因在路徑上的過濾策略,而非伺服器本身。
管理多台主機時,建議維護一份公網 IP 與 SSH 埠的對照表。從舊工單複製貼上錯 IP 的情況出乎意料地常見,尤其在雲端遷移實例或重新分配彈性 IP 之後。
用網域名稱連線時,記得考慮 TTL 與快取。你可能五分鐘前才更新 DNS,但筆電或上游解析器仍指向舊位址——以本機的 dig +short 為準,別只看註冊商後台。
方法二:檢查 sshd 服務是否在運行
Connection refused 最常見的原因之一:sshd 根本沒啟動,或系統升級後服務名稱變了。Ubuntu/Debian 上通常是 ssh;RHEL/CentOS/Rocky 則是 sshd。別猜,用指令確認。
透過 VNC 或雲端主控台登入後執行:
# Debian/Ubuntu sudo systemctl status ssh sudo systemctl start ssh sudo systemctl enable ssh # RHEL/CentOS/Rocky sudo systemctl status sshd sudo systemctl start sshd # Is it listening? Which address and port? sudo ss -tlnp | grep ssh # Expect 0.0.0.0:22 or [::]:22 # Config syntax check (run after every edit) sudo sshd -t sudo systemctl reload ssh # or sshd
若 systemctl status 顯示 failed,立刻查日誌:sudo journalctl -u ssh -n 50 --no-pager。常見致命錯誤包括設定檔拼寫錯誤、HostKey 檔案遺失、ListenAddress 綁在錯誤的網卡上。每次修改後務必先跑 sshd -t 再 reload——我們見過太多人改完直接 reload,結果 sshd 起不來,把自己鎖在門外。
剛重裝的系統,請確認 openssh-server 已安裝:sudo apt install openssh-server(Debian 系)或 sudo dnf install openssh-server(RHEL 系)。精簡雲端映像有時預設不帶 SSH 伺服器。
磁碟滿了也可能導致 sshd 無法啟動或接受連線。從主控台快速跑 df -h,往往比遠端苦思十分鐘划算。若有人在暴力破解期間把 MaxStartups 設得太嚴,高負載時合法客戶端也可能看到 refused——查 journalctl 是否有「drop connection」訊息。
部分升級後若共存多個 sshd 版本,which sshd 與 systemd 單元的 ExecStart 路徑應一致。二進位與設定路徑錯位會製造「昨天還好好的」這類困惑事件。
方法三:檢查本機防火牆與雲端安全群組
sshd 在跑、ss 也看得到監聽,但外面仍 refused——下一個嫌疑是防火牆規則丟棄或拒絕流量。Linux 伺服器通常疊兩層:雲端安全群組(網卡外側)與系統內 ufw/iptables/nftables(網卡內側)。兩層都必須放行 SSH 埠。
系統內常用檢查指令:
sudo ufw status verbose
sudo ufw allow 22/tcp
sudo ufw allow 2222/tcp # if you changed the port
sudo ufw reload
# firewalld (CentOS, etc.)
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
# Inspect nftables/iptables directly
sudo iptables -L INPUT -n -v
雲端安全群組必須在供應商主控台修改——SSH 掛了時,筆電上沒有魔法 CLI 能代勞。三個細節:協定是 TCP、埠範圍包含你的 SSH 埠、來源 CIDR 沒有誤設成只有某台內網主機。測試階段可暫時開到 0.0.0.0/0;確認能連後再收緊到辦公室出口 IP。
若 VPS 上跑了 Docker 或 Kubernetes,iptables 規則可能被自動改寫。執行 sudo iptables-save | grep 22,看 ACCEPT 前面是否插了 DROP 或 REJECT。關於最小暴露面與 SSH/HTTPS 埠取捨,可參考我們的 Linux 雲主機最小暴露面防火牆 SSH/HTTPS 決策 FAQ。
IPv6 是常見盲點:你可能只修了 IPv4 安全群組,但 ssh user@host 優先走 AAAA 記錄,撞上被擋的 v6 路徑。行為不一致時,用 ssh -4 和 ssh -6 分別測試。
記下是哪一層擋了你。只修 ufw 卻忘了安全群組的團隊,下次有人「強化資安」時往往重演同一場 outage。
方法四:核對埠與 sshd_config 設定
許多管理員會把 SSH 改到非 22 埠,或把 ListenAddress 限在內網介面。客戶端仍連 22 就會 refused。伺服器設定在 /etc/ssh/sshd_config。關鍵指令(完整說明見 sshd_config 手冊):
Port 2222
# ListenAddress 0.0.0.0 # default: all interfaces; 127.0.0.1 blocks external access
PermitRootLogin prohibit-password
PasswordAuthentication no
AllowUsers deploy admin
安全的改埠流程:先確認新埠在監聽,再更新防火牆,最後才關舊埠。別一步到位的魯莽操作——「把 22 改成 2222 並立刻關閉安全群組 22」這類做法,常在驗證新埠前就讓人失聯。
RHEL 系若啟用 SELinux,改埠後需執行 sudo semanage port -a -t ssh_port_t -p tcp 2222,否則 sshd 可能無法綁定。Ubuntu 的 AppArmor 也可能限制路徑,日誌會寫得很清楚。
客戶端側請再檢查 ~/.ssh/config 是否寫錯 Port 或 HostName。團隊用 Host prod 別名時,複製指令漏了 -p 是常見失誤。
AllowUsers 與 DenyUsers 可能製造困惑:TCP 連上了,sshd 有回應,接著認證失敗——或在某些設定下連線提早關閉。若最近收緊使用者政策,請比對本機使用者名稱與伺服器允許清單。
跳板機與 ProxyJump 又多一個變數。最後一跳的 refused 可能代表堡壘機沒問題,但目標主機的埠或安全群組有問題。用 ssh -J 與從堡壘對內網主機跑 nc,逐段測試。
方法五:排查 IP 封鎖(fail2ban / hosts.deny)
若你看到的是 Permission denied 而非 refused,但確定金鑰沒問題,就要懷疑 IP 被封。fail2ban 會在多次密碼失敗或異常握手後,往 iptables 或 hosts.deny 寫入規則。fail2ban Wiki 對 jail 機制有深入說明。
在伺服器上檢查:
# fail2ban status sudo fail2ban-client status sshd sudo fail2ban-client set sshd unbanip YOUR.CLIENT.IP # Classic hosts-based bans grep -v '^#' /etc/hosts.deny grep -v '^#' /etc/hosts.allow # Cloud "ops lock" or DDoS mitigation # → check provider console for security alerts or temporary IP blocks
把自己封進去並不罕見:腳本誤觸、幾秒內大量失敗登入,fail2ban 就把辦公室出口 IP 送進 jail。解封後建議把管理員 IP 加入 ignoreip,或關閉密碼認證、只用金鑰,從源頭減少誤封。
若你同時跑 Jenkins、GitLab Runner 等需要回連 VPS 的 Agent,註冊失敗有時也會表現得像 SSH 異常。混合拓撲下,Controller 與 Agent 的網路路徑值得單獨畫圖——可參考 Jenkins 混合拓撲:VPS Controller 與雲端 Mac JNLP 企業資源池。
Cloudflare 等代理不會像處理 HTTP 那樣在 22 埠終止 SSH。若你誤把錯誤服務掛到代理後面,或搞混堡壘機與應用程式的 DNS,請退一步釐清哪個主機名稱本來就該暴露 SSH。
徹底被鎖在外面時:走救援通道
若上述五步仍無法恢復,請依序嘗試:
- 雲端 VNC / 序列埠主控台——不依賴 SSH,直接登入修設定
- 快照還原——若變更前有快照,還原比通宵排障划算
- 單使用者模式 / Rescue 映像——掛載原磁碟、chroot 進去改
sshd_config - 提支援工單——部分供應商可暫時開放埠或解除封鎖
教訓很簡單:永遠別在唯一的 SSH 連線上做「可能斷線」的變更。開第二個終端機保持連線,或用 tmux;改防火牆與 sshd 設定時尤其如此。
恢復後寫三行事後檢討:改了什麼、漏看了哪個訊號、哪條備用管道救了你。下一個 on-call 會感謝你。
預防清單:下次少慌一輪
事件結束後花十分鐘收尾,比下次再 panic 值得:
- 金鑰登入、關閉密碼;
~/.ssh/authorized_keys權限 600 - SSH 可改非標準埠——安全群組與 sshd_config 要一起改
- 設定 fail2ban
ignoreip,別把自己人封了 - reload 前先跑
sshd -t;高風險變更前先打快照 - 監控別只靠「SSH 22 埠 up/down」——用 Agent 或內網健康檢查
考慮專用堡壘機搭配穩定出口 IP,生產節點的安全群組只放行堡壘。你筆電在咖啡廳的 IP 不該是唯一的鑰匙。
穩定跳板機:排障少一層焦慮
管理多台 Linux VPS 時,許多團隊會備一台固定出口 IP 的跳板機做 SSH 中轉——生產安全群組只放行堡壘,本機用金鑰串連進去。Mac mini 很適合這個角色:原生 Unix 環境,Terminal 與 OpenSSH 開箱即用;M4 晶片待機約 4W,安靜到可以 7×24 掛在桌上當中繼節點——比桌下再開一台 x86 小主機更省電、更安靜。
同價位的 Windows 機器長期開著當跳板,功耗與風扇噪音都更高;macOS 以長時間穩定著稱,搭配 FileVault 與 Gatekeeper,存放私鑰也較安心。若你還要在同一台機器上用 Xcode 或 Docker 做發布,雲端 Mac mini 可以把跳板 + 建置合併到單一節點,減少來回切換。
若你正在規劃可靠的遠端維運環境, VPSSPark 雲端 Mac mini M4 是低功耗跳板與開發節點的務實選擇—— 查看方案與定價 ,讓 SSH 排障不再是凌晨兩點的獨角戲。