在進行基礎架構建置時,常見的問題之一就是「無法 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 是兩回事。
本文將透過 ping、traceroute 與 SSH,整理在無法 SSH 時,如何分辨目前網路通到哪裡、哪個環節出問題的思考方式。
ping 可以看出什麼traceroute 可以看出什麼SSH 無法連線時,可以用下面的方式來整理。
確認方式範例指令可得知什麼到達性ping <IP>對方是否有回 ICMP 回應路由traceroute <IP>途中哪一段有回應連接埠nc -vz <IP> 22 / telnet <IP> 22是否到得了 TCP 22 埠 SSH 連線ssh -v user@<IP>SSH 連線或驗證在哪裡失敗重點在於,每個工具確認的東西都不同。
* * *,也不代表一定無法 SSH無法 SSH 的原因,大致可分為以下幾類。
分類範例路由問題沒有路由、途中網路設備阻擋防火牆 / 安全群組 / 網路 ACL 問題 TCP 22 埠未開放伺服器端問題 sshd 沒有啟動驗證問題 使用者名稱、金鑰、密碼錯誤名稱解析問題 主機名稱沒有解析到預期的 IP 也就是說,單純說「無法 SSH」時,需要檢查的地方其實很多。
因此,不要一開始就只看 SSH 設定,而是要按順序確認,目前到底通到哪裡、又是從哪裡開始不通
。
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
這時可以這樣理解:
但這裡最重要的是:
ping 通 ≠ 能 SSH
因為 ping 和 SSH 使用的通訊不同。
種類使用的通訊 ping ICMP SSH TCP 22 埠
所以,即使 ping 通了,只要 TCP 22 埠被關閉,SSH 還是無法連線。
反過來說,ping 不通也不一定代表 SSH 不通。
有些安全設定會封鎖 ICMP,但仍允許 SSH 的 TCP 22 埠,這種情況也存在。
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,因此即使中途出現 * * *,最後仍可能成功到達目的地。
對初學者來說,不需要一開始就把所有路徑細節都理解透徹。先看下面這些就夠了。
觀察重點意義第一行是否有回應是否連自己的附近閘道都能到從中途開始是否一直是 * * *是否在途中開始無回應最後是否有顯示目的地 IP是否有回應到目的地是否走了意料之外的路徑路由可能與預期不同不過,traceroute 只是路徑確認的線索而已。SSH 使用的 TCP 22 埠是否能通,仍需要另外確認。
無法 SSH 時,首先要確認錯誤訊息。
ssh: connect to host 192.168.1.100 port 22: Connection timed out
這表示 SSH 連線沒有收到回應。常見原因如下:
ssh: connect to host 192.168.1.100 port 22: Connection refused
這表示封包有到達對方,但對方沒有在 22 埠接受連線。常見原因如下:
Permission denied (publickey).
這表示 SSH 伺服器已經連上了,但驗證失敗。常見原因如下:
authorized_keys 權限設定不正確這種情況下,應該優先懷疑的是驗證設定,而不是網路。
只有 ping 和 traceroute,無法判斷是否能到達 SSH 使用的 TCP 22 埠。因此,要用 nc 或 telnet 來確認 22 埠。
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 的通訊沒有得到回應。此時請確認:
telnet 192.168.1.100 22
若成功,可能會顯示 SSH 伺服器的 banner。
SSH-2.0-OpenSSH_8.9
SSH 無法連線時,照下面順序確認會比較容易整理。
① 先看 SSH 錯誤訊息
├─ Permission denied
│ └─ 檢查驗證、使用者名稱、金鑰
│
├─ Connection refused
│ └─ 檢查 sshd 啟動狀態、監聽埠
│
└─ Connection timed out
└─ 檢查路由、防火牆、安全群組、網路 ACL、伺服器狀態
② 用 ping 確認是否有回應
├─ 有回應
│ └─ ICMP 有回應,但不代表一定能 SSH
│
└─ 沒回應
└─ 懷疑 ICMP 被拒、路由問題、伺服器停止等
③ 用 traceroute 確認路徑
├─ 有顯示到目的地
│ └─ 路徑大致上沒問題
│
├─ 中途持續出現 * * *
│ └─ 懷疑中途設備不回應,或路由 / 防火牆問題
│
└─ 一開始就沒回應
└─ 檢查本機、閘道、路由設定
④ 確認 22 埠
├─ 連線成功
│ └─ 檢查驗證與 SSH 設定
│
├─ timed out
│ └─ 檢查防火牆、安全群組、網路 ACL、路由
│
└─ refused
└─ 檢查 sshd 是否停止、監聽埠是否正確
pingtraceroute 22 埠SSH可能的原因成功可看到目的地成功成功沒有問題成功可看到目的地成功Permission denied驗證資訊有問題成功可看到目的地refused失敗sshd 停止、監聽埠不對成功中途停止成功成功/失敗 traceroute 回應被拒絕的可能失敗中途停止timed out失敗路由、防火牆、安全群組、網路 ACL、回程路徑問題失敗中途停止成功成功ICMP / traceroute 可能被拒絕失敗失敗失敗失敗可能是目的地 IP 錯誤、伺服器停止、沒有路由
在 AWS 上對 EC2 進行 SSH 時,如果連不上,不只要看作業系統內部,也要確認 AWS 端的設定。
確認項目重點安全群組是否在 inbound 規則允許 TCP 22 埠網路 ACL 是否以子網層級拒絕路由表 是否存在從連線來源到目標子網的路由子網 是否為預期中的公有 / 私有配置 Internet Gateway / NAT / TGW / Peering 路徑上是否有必要的連線 EC2 狀態 執行個體是否已啟動作業系統防火牆 firewalld、iptables、ufw 等是否有拒絕 sshd SSH 服務是否已啟動金鑰 / 使用者名稱 是否使用正確的私密金鑰與使用者名稱
特別是在 AWS 上,很常遇到以下情況:
在 AWS 中,只看伺服器內部有時無法找出原因。VPC、子網、路由表、安全群組、網路 ACL 也必須一起檢查,這點很重要。
無法 SSH 時,最重要的是:
把「已經通了什麼」和「還沒通什麼」分開思考
ping 是看 ICMP 回應traceroute 是看途中路徑的回應nc 和 telnet 是看能不能到 TCP 22 埠ssh 是連 SSH 與驗證一起確認也就是說,每個工具確認的範圍都不一樣。
指令可確認的內容不可確認的內容pingICMP 回應能不能 SSHtraceroute途中路徑的回應 TCP 22 埠是否通nc -vz <IP> 22TCP 22 埠是否連得通認證是否成功ssh -v user@<IP>SSH 連線與驗證細節整體路徑細節不要只靠一個指令就下結論,而是要意識到已經確認到哪裡、哪裡還沒確認
,這樣排查問題會輕鬆很多。
當 SSH 無法連線時,按照下面流程確認,就比較容易縮小原因範圍。
ping 確認 ICMP 回應traceroute 確認途中路徑nc 或 telnet 確認 TCP 22 埠ping 通,不代表就一定能 SSH。
traceroute 中途停止,也不代表一定無法通訊。
最重要的是,理解每個指令是在確認什麼,並按順序逐步排查。
把「無法 SSH」這種模糊狀態拆解成:
就能更接近真正原因。
剛開始做基礎架構建置時,遇到 SSH 連不上,前輩常會問「ping 呢?」「traceroute 呢?」之類的問題;如果你懂得如何切分問題,即使最後還是無法 SSH,也能清楚說出「我已經確認到這裡了!」,處理起來會順很多。
即使沒有經驗也能學!一起挑戰吧!
原文出處:https://qiita.com/M_waowaowao/items/803300d3453daaaf48ce