VPSSPark 部落格
← 返回開發日記

Linux 伺服器 SSH 連線被拒的 5 種排查方法

機房手記 · 2026.07.17 · 約 11 分鐘閱讀

常見搜尋:SSH 連線被拒 · Connection refused · Linux VPS 遠端登入失敗 · sshd 排障

開發者俯拍多螢幕工作站,顯示器上是程式碼與終端機——Linux 伺服器 SSH 遠端排障場景
SSH 連不上時,多數人第一反應是「伺服器掛了」——其實八成是連接埠、防火牆或服務設定,分層排查比盲目重啟快得多。

你剛開好一台 Linux VPS,或是凌晨兩點監控告警說 SSH 登不進去。終端機跳出一行 ssh: connect to host … port 22: Connection refused,心跳立刻加快。更糟的是:手邊沒有 VNC、沒有雲端主控台,只能對著閃爍游標發呆。

這類問題我們每個月都會遇到幾次——有時是新人改完 sshd_config 忘了 reload,有時是安全群組只開了 80/443 卻漏了 22,還有時是 fail2ban 把你家寬頻的 IP 悄悄封了。好消息是:SSH 連線被拒通常有跡可循,不需要靠玄學。本文把實戰裡最高頻的五條排查路徑整理成清單,按「先讀報錯、再分層」的順序走,大多數情況二十分鐘內能定位根因。

前提說明:下文假設你還有某種備用登入管道——雲端 VNC、序列埠主控台,或同一 VPC 內的另一台機器。若完全失聯,請直接跳到 徹底被鎖在外面時怎麼辦

22
SSH 預設埠
3
常見報錯類型
5
分層排查路徑

排障前必做:三種「連不上」不是一回事

很多人把 Connection refusedConnection timed outPermission denied 混為一談,排查方向就完全偏了。根據 OpenSSH 官方文件,這三者分別指向堆疊的不同層級:

Linux SSH 連線被拒五步排查流程:讀報錯、查服務、查防火牆、查埠設定、查 IP 封鎖
先依報錯訊息選對分支,再按網路 → 服務 → 策略的順序排查,避免在金鑰權限上白忙一小時。
報錯關鍵字 通常代表什麼 優先檢查
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 連線。

請在本機依序執行:

Client-side network probes
# 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 或雲端主控台登入後執行:

Server-side sshd status
# 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 埠。

系統內常用檢查指令:

Firewall checks (Ubuntu ufw example)
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 -4ssh -6 分別測試。

改防火牆前的保命習慣
在關閉目前 SSH 連線之前,先設一個計時回滾:五分鐘後自動恢復舊規則(或排程關閉 ufw)。若新規則把你鎖在外面,還有搶救窗口。

記下是哪一層擋了你。只修 ufw 卻忘了安全群組的團隊,下次有人「強化資安」時往往重演同一場 outage。

方法四:核對埠與 sshd_config 設定

許多管理員會把 SSH 改到非 22 埠,或把 ListenAddress 限在內網介面。客戶端仍連 22 就會 refused。伺服器設定在 /etc/ssh/sshd_config。關鍵指令(完整說明見 sshd_config 手冊):

sshd_config essentials
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 是否寫錯 PortHostName。團隊用 Host prod 別名時,複製指令漏了 -p 是常見失誤。

AllowUsersDenyUsers 可能製造困惑:TCP 連上了,sshd 有回應,接著認證失敗——或在某些設定下連線提早關閉。若最近收緊使用者政策,請比對本機使用者名稱與伺服器允許清單。

跳板機與 ProxyJump 又多一個變數。最後一跳的 refused 可能代表堡壘機沒問題,但目標主機的埠或安全群組有問題。用 ssh -J 與從堡壘對內網主機跑 nc,逐段測試。

方法五:排查 IP 封鎖(fail2ban / hosts.deny)

若你看到的是 Permission denied 而非 refused,但確定金鑰沒問題,就要懷疑 IP 被封。fail2ban 會在多次密碼失敗或異常握手後,往 iptables 或 hosts.deny 寫入規則。fail2ban Wiki 對 jail 機制有深入說明。

在伺服器上檢查:

Ban inspection
# 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 不該是唯一的鑰匙。

一句話總結
先讀報錯,分清 refused、timeout、denied——再一層層剝:網路 → 服務 → 防火牆 → 設定 → 封鎖。多數 SSH 連線被拒在第二步或第三步就能解決。

穩定跳板機:排障少一層焦慮

管理多台 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 排障不再是凌晨兩點的獨角戲。

限時特惠

SSH 斷了別慌——先備好穩定的雲端節點

低功耗 Mac mini · 原生 Unix 跳板環境 · 7×24 靜默在線

返回首頁
限時優惠 點擊查看套餐