前言

在進行基礎架構建置時,常見的問題之一就是「無法 SSH 連線」。

例如,假設你要 SSH 到一台新建立的 Linux 伺服器。

ssh [email protected]

但等了很久還是無法連線,並回傳如下錯誤:

ssh: connect to host 192.168.1.100 port 22: Connection timed out

你可能會想:「該不會是伺服器掛了吧?」於是執行 ping,結果卻有回應。

ping 192.168.1.100
64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=1.2 ms

這時初學者最容易困惑的問題就是:

明明 ping 得通,為什麼卻無法 SSH?

實際上,ping 通不通和能不能 SSH 是兩回事。

本文將透過 pingtracerouteSSH,整理在無法 SSH 時,如何分辨目前網路通到哪裡、哪個環節出問題的思考方式。


本文可了解的內容

  • ping 可以看出什麼
  • traceroute 可以看出什麼
  • 從 SSH 錯誤訊息該懷疑什麼
  • 為什麼 ping 通了還是無法 SSH
  • 應該按照什麼順序確認
  • AWS 環境中應該查看哪些重點

先講結論

SSH 無法連線時,可以用下面的方式來整理。

確認方式範例指令可得知什麼到達性ping <IP>對方是否有回 ICMP 回應路由traceroute <IP>途中哪一段有回應連接埠nc -vz <IP> 22 / telnet <IP> 22是否到得了 TCP 22 埠 SSH 連線ssh -v user@<IP>SSH 連線或驗證在哪裡失敗重點在於,每個工具確認的東西都不同

  • ping 通,不代表一定能 SSH
  • traceroute 中途出現 * * *,也不代表一定無法 SSH
  • SSH 無法連線的原因,要分成網路、連接埠、服務、驗證等面向來看

1. 無法 SSH 的原因不只一種

無法 SSH 的原因,大致可分為以下幾類。

分類範例路由問題沒有路由、途中網路設備阻擋防火牆 / 安全群組 / 網路 ACL 問題 TCP 22 埠未開放伺服器端問題 sshd 沒有啟動驗證問題 使用者名稱、金鑰、密碼錯誤名稱解析問題 主機名稱沒有解析到預期的 IP 也就是說,單純說「無法 SSH」時,需要檢查的地方其實很多。

因此,不要一開始就只看 SSH 設定,而是要按順序確認,目前到底通到哪裡、又是從哪裡開始不通


2. ping 可以看出什麼

ping 是用來對目標 IP 傳送 ICMP 通訊,確認對方是否有回應的指令。

ping 192.168.1.100

如果有回應,至少代表 ICMP 層面上,對方有回傳訊息。

64 bytes from 192.168.1.100: icmp_seq=1 ttl=64 time=1.2 ms

這時可以這樣理解:

  • 目標 IP 大致上沒有打錯
  • 對方有回應
  • ICMP 通訊看起來是允許的

但這裡最重要的是:

ping 通 ≠ 能 SSH

因為 ping 和 SSH 使用的通訊不同。

種類使用的通訊 ping ICMP SSH TCP 22 埠

所以,即使 ping 通了,只要 TCP 22 埠被關閉,SSH 還是無法連線。

反過來說,ping 不通也不一定代表 SSH 不通。
有些安全設定會封鎖 ICMP,但仍允許 SSH 的 TCP 22 埠,這種情況也存在。


3. traceroute 可以看出什麼

traceroute 是用來確認到目的地的途中路徑上,是哪一段開始有回應的指令。

在 Linux 中可這樣執行:

traceroute 192.168.1.100

在 Windows 中則使用 tracert

tracert 192.168.1.100

結果範例如下:

traceroute to 192.168.1.100 (192.168.1.100), 30 hops max
 1  192.168.0.1  1.123 ms  1.045 ms  1.001 ms
 2  10.0.0.1     3.456 ms  3.421 ms  3.398 ms
 3  * * *
 4  * * *

* * * 表示該位置沒有收到回應。

在這個例子中,前兩跳有回應,但從第三跳開始就沒有回應了。

不過這裡也要注意:

*traceroute 出現 ` ` ≠ 一定無法通訊**

途中路由器或防火牆有可能被設定成不回應 traceroute,因此即使中途出現 * * *,最後仍可能成功到達目的地。


4. traceroute 要看什麼重點

對初學者來說,不需要一開始就把所有路徑細節都理解透徹。先看下面這些就夠了。

觀察重點意義第一行是否有回應是否連自己的附近閘道都能到從中途開始是否一直是 * * *是否在途中開始無回應最後是否有顯示目的地 IP是否有回應到目的地是否走了意料之外的路徑路由可能與預期不同不過,traceroute 只是路徑確認的線索而已。SSH 使用的 TCP 22 埠是否能通,仍需要另外確認。


5. 查看 SSH 錯誤訊息

無法 SSH 時,首先要確認錯誤訊息。

Connection timed out

ssh: connect to host 192.168.1.100 port 22: Connection timed out

這表示 SSH 連線沒有收到回應。常見原因如下:

  • TCP 22 埠被防火牆擋住
  • 在 AWS 中,安全群組未允許 22 埠
  • 被網路 ACL 拒絕
  • 伺服器已停止
  • 路由或回程流量有問題

Connection refused

ssh: connect to host 192.168.1.100 port 22: Connection refused

這表示封包有到達對方,但對方沒有在 22 埠接受連線。常見原因如下:

  • sshd 沒有啟動
  • SSH 監聽的埠不是 22
  • 伺服器端拒絕連線

Permission denied

Permission denied (publickey).

這表示 SSH 伺服器已經連上了,但驗證失敗。常見原因如下:

  • 使用者名稱錯誤
  • 私密金鑰錯誤
  • 公開金鑰沒有登錄到伺服器上
  • authorized_keys 權限設定不正確
  • 密碼驗證已停用

這種情況下,應該優先懷疑的是驗證設定,而不是網路。


6. 確認是否到得了 22 埠

只有 pingtraceroute,無法判斷是否能到達 SSH 使用的 TCP 22 埠。因此,要用 nctelnet 來確認 22 埠。

使用 nc

nc -vz 192.168.1.100 22

成功範例

Connection to 192.168.1.100 22 port [tcp/ssh] succeeded!

這表示 TCP 22 埠已經可以連到。即使如此若仍無法 SSH,就要檢查使用者名稱、金鑰、驗證方式等設定。

失敗範例

nc: connect to 192.168.1.100 port 22 timed out

這表示對 TCP 22 的通訊沒有得到回應。此時請確認:

  • 安全群組
  • 網路 ACL
  • 作業系統防火牆
  • 路由表
  • 伺服器啟動狀態
  • sshd 啟動狀態

使用 telnet

telnet 192.168.1.100 22

若成功,可能會顯示 SSH 伺服器的 banner。

SSH-2.0-OpenSSH_8.9

如果出現這個畫面,就表示已經到達 SSH 伺服器的 22 埠。

7. 切分排查流程

SSH 無法連線時,照下面順序確認會比較容易整理。

① 先看 SSH 錯誤訊息
  ├─ Permission denied
  │   └─ 檢查驗證、使用者名稱、金鑰
  │
  ├─ Connection refused
  │   └─ 檢查 sshd 啟動狀態、監聽埠
  │
  └─ Connection timed out
      └─ 檢查路由、防火牆、安全群組、網路 ACL、伺服器狀態

② 用 ping 確認是否有回應
  ├─ 有回應
  │   └─ ICMP 有回應,但不代表一定能 SSH
  │
  └─ 沒回應
      └─ 懷疑 ICMP 被拒、路由問題、伺服器停止等

③ 用 traceroute 確認路徑
  ├─ 有顯示到目的地
  │   └─ 路徑大致上沒問題
  │
  ├─ 中途持續出現 * * *
  │   └─ 懷疑中途設備不回應,或路由 / 防火牆問題
  │
  └─ 一開始就沒回應
      └─ 檢查本機、閘道、路由設定

④ 確認 22 埠
  ├─ 連線成功
  │   └─ 檢查驗證與 SSH 設定
  │
  ├─ timed out
  │   └─ 檢查防火牆、安全群組、網路 ACL、路由
  │
  └─ refused
      └─ 檢查 sshd 是否停止、監聽埠是否正確

8. 判斷表

pingtraceroute 22 埠SSH可能的原因成功可看到目的地成功成功沒有問題成功可看到目的地成功Permission denied驗證資訊有問題成功可看到目的地refused失敗sshd 停止、監聽埠不對成功中途停止成功成功/失敗 traceroute 回應被拒絕的可能失敗中途停止timed out失敗路由、防火牆、安全群組、網路 ACL、回程路徑問題失敗中途停止成功成功ICMP / traceroute 可能被拒絕失敗失敗失敗失敗可能是目的地 IP 錯誤、伺服器停止、沒有路由


9. AWS 環境中要看的重點

在 AWS 上對 EC2 進行 SSH 時,如果連不上,不只要看作業系統內部,也要確認 AWS 端的設定。

確認項目重點安全群組是否在 inbound 規則允許 TCP 22 埠網路 ACL 是否以子網層級拒絕路由表 是否存在從連線來源到目標子網的路由子網 是否為預期中的公有 / 私有配置 Internet Gateway / NAT / TGW / Peering 路徑上是否有必要的連線 EC2 狀態 執行個體是否已啟動作業系統防火牆 firewalld、iptables、ufw 等是否有拒絕 sshd SSH 服務是否已啟動金鑰 / 使用者名稱 是否使用正確的私密金鑰與使用者名稱

特別是在 AWS 上,很常遇到以下情況:

  • 安全群組沒有允許 22 埠
  • 連線來源 IP 改變,已不在允許的 CIDR 範圍內
  • 網路 ACL 沒有允許回程流量
  • 路由表沒有回程路由
  • 透過跳板機的路徑與預期不同
  • EC2 明明已啟動,但 sshd 卻停止了

在 AWS 中,只看伺服器內部有時無法找出原因。VPC、子網、路由表、安全群組、網路 ACL 也必須一起檢查,這點很重要。


10. 想對初學者特別強調的一件事

無法 SSH 時,最重要的是:

把「已經通了什麼」和「還沒通什麼」分開思考

  • ping 是看 ICMP 回應
  • traceroute 是看途中路徑的回應
  • nctelnet 是看能不能到 TCP 22 埠
  • ssh 是連 SSH 與驗證一起確認

也就是說,每個工具確認的範圍都不一樣。

指令可確認的內容不可確認的內容pingICMP 回應能不能 SSHtraceroute途中路徑的回應 TCP 22 埠是否通nc -vz <IP> 22TCP 22 埠是否連得通認證是否成功ssh -v user@<IP>SSH 連線與驗證細節整體路徑細節不要只靠一個指令就下結論,而是要意識到已經確認到哪裡、哪裡還沒確認
,這樣排查問題會輕鬆很多。


總結

當 SSH 無法連線時,按照下面流程確認,就比較容易縮小原因範圍。

  1. 先看 SSH 錯誤內容
  2. ping 確認 ICMP 回應
  3. traceroute 確認途中路徑
  4. nctelnet 確認 TCP 22 埠
  5. 如果 22 埠可達,再檢查使用者名稱、金鑰、驗證設定
  6. 在 AWS 環境中,也要確認安全群組、網路 ACL、路由表

ping 通,不代表就一定能 SSH。
traceroute 中途停止,也不代表一定無法通訊。

最重要的是,理解每個指令是在確認什麼,並按順序逐步排查

把「無法 SSH」這種模糊狀態拆解成:

  • ICMP 有回應
  • 路徑只看到這裡
  • TCP 22 埠無法到達
  • 22 埠可以到達但驗證失敗

就能更接近真正原因。
剛開始做基礎架構建置時,遇到 SSH 連不上,前輩常會問「ping 呢?」「traceroute 呢?」之類的問題;如果你懂得如何切分問題,即使最後還是無法 SSH,也能清楚說出「我已經確認到這裡了!」,處理起來會順很多。


:sparkles:即使沒有經驗也能學!一起挑戰吧!:sparkles:

我也有在經營 note ↓
https://note.com/jqit_itsaiyo


原文出處:https://qiita.com/M_waowaowao/items/803300d3453daaaf48ce


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝6   💬2  
337
🥈
我愛JS
💬1  
3
🥉
alicec
1
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登