SSH 是什麼意思?工作原理、22 連接埠與 Telnet 的區別
SSH 是 Secure Shell 的縮寫,中文常叫安全外殼協議,是一種在不可信網路上加密傳輸的遠端管理協議:所有內容先加密再傳送,還能驗證你連上的確實是那台伺服器。它預設使用 TCP 22 連接埠,除了登入伺服器和交換器執行命令,還用來傳檔案、做連接埠轉發和自動化維運,已經全面取代明文傳輸的 Telnet。
SSH 是什麼意思?SSH 是 Secure Shell 的縮寫,可以理解為“安全的遠端命令列”:它是一種網路協議,讓你在自己的電腦上開啟一個終端,就像坐在伺服器前一樣執行命令,而一路上傳輸的帳號、密碼、命令和輸出全部是加密的。SSH 最早由芬蘭的 Tatu Ylönen 在 1995 年設計,現行的 SSH-2 由 IETF 在 2006 年以 RFC 4251–4254 標準化;伺服器上最常見的實現是 OpenSSH。服務端程式 sshd 預設監聽 TCP 22 連接埠,客戶端就是 Linux、macOS 和 Windows 10/11 都自帶的 ssh 命令,以及各種圖形化終端工具。
SSH 是幹什麼的:五種常見用途
| 用途 | 範例 | 說明 |
|---|---|---|
| 遠端登入 | ssh [email protected] |
開啟遠端 shell,管理 Linux 伺服器,以及交換器、BMC 的命令列 |
| 遠端執行命令 | ssh [email protected] 'df -h' |
不進入互動介面,執行完就返回結果,適合指令碼和巡檢 |
| 傳輸檔案 | sftp [email protected]、scp app.tar.gz [email protected]:/tmp/ |
SFTP、SCP 走同一條 SSH 連線、同一個連接埠;OpenSSH 9.0 起 scp 預設改用 SFTP 協議傳輸 |
| 連接埠轉發與隧道 | ssh -L 8443:10.20.0.15:443 [email protected] |
把只在內網開放的服務,經過加密的 SSH 連線臨時帶出來 |
| 自動化與程式碼同步 | Ansible、git clone [email protected]:ops/scripts.git |
Ansible 預設透過 SSH 登入被管主機;Git 託管平台用 SSH 金鑰認證 |
這五種用途都基於同一個能力:在兩台機器之間建立一條經過身份驗證的加密通道,然後在裡面跑終端、命令、檔案或任意 TCP 流量。
SSH 協議是怎麼工作的:三層結構與連線過程
三層結構
SSH-2 由三個協議疊在一起組成,RFC 4251 描述了整體架構:
| 層 | 標準 | 負責什麼 | 你在使用中會碰到的 |
|---|---|---|---|
| 傳輸層協議 | RFC 4253 | 在 TCP 之上協商演算法、交換金鑰、驗證伺服器身份,之後所有資料加密並做完整性校驗 | 首次連線的指紋提示;no matching key exchange method 之類的報錯 |
| 使用者認證協議 | RFC 4252 | 在已加密的通道里驗證“你是誰”:公鑰、密碼、鍵盤互動(可接動態口令)等 | Permission denied (publickey,password) |
| 連線協議 | RFC 4254 | 在一條連線裡複用多個通道:互動式會話、遠端命令、SFTP 子系統、連接埠轉發 | 一條連線裡同時開 shell、傳檔案和轉發連接埠 |
順序很關鍵:先建立加密通道、確認伺服器身份,再做使用者認證。使用者名稱和密碼都是在加密之後才發出去的。
一次連線的建立過程
- TCP 三次握手,連上伺服器的 22 連接埠。
- 交換版本號:雙方各發一行明文,如
SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13,確認都使用 SSH-2。 - 協商演算法:雙方各列出自己支援的金鑰交換、主機金鑰、加密、完整性校驗和壓縮演算法,按客戶端列表的順序取第一個雙方都支援的。
- 金鑰交換:用 Diffie-Hellman 類演算法(如 curve25519-sha256,較新的 OpenSSH 預設使用加入了抗量子演算法的混合方案),雙方各生成一對臨時金鑰,只交換公鑰部分,各自算出同一個共享金鑰。竊聽者看到全部交換內容,也算不出這個金鑰。
- 伺服器證明身份:伺服器用自己的主機私鑰,對這次金鑰交換的摘要做簽名;客戶端用主機公鑰驗籤,並與本地
known_hosts裡記錄的公鑰比對。首次連線時“是否信任這個指紋”的提示,就發生在這一步。 - 啟用加密:雙方從共享金鑰派生出加密和校驗用的會話金鑰,此後每個報文都加密,並帶完整性校驗。
- 使用者認證:客戶端申請認證服務,用公鑰或密碼證明身份。
- 開啟通道:認證透過後開啟一個會話通道,申請終端、啟動 shell,出現命令提示符。
會話金鑰由臨時金鑰派生,連線結束就丟棄。即使將來伺服器的主機私鑰洩露,之前被錄下來的流量也無法解密,這叫前向保密。
用 ssh -v 看每一步
ssh -v 列印的除錯資訊正好對應上面的八步。下面是 OpenSSH 9.6 客戶端連線同版本伺服器的輸出節選,不同版本的措辭略有差異:
ssh -v [email protected]
debug1: Connecting to 203.0.113.10 [203.0.113.10] port 22.
debug1: Connection established.
debug1: Local version string SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.6p1 Ubuntu-3ubuntu13
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: [email protected]
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none
debug1: SSH2_MSG_KEX_ECDH_REPLY received
debug1: Host '203.0.113.10' is known and matches the ED25519 host key.
debug1: SSH2_MSG_NEWKEYS sent
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
Authenticated to 203.0.113.10 ([203.0.113.10]:22) using "publickey".
debug1: Entering interactive session.
| 輸出 | 對應步驟 |
|---|---|
Connecting to、Connection established. |
第 1 步,TCP 連上 22 連接埠 |
Local version string、Remote protocol version 2.0 |
第 2 步,交換版本號 |
KEXINIT 和幾行 kex: |
第 3 步,協商出金鑰交換、主機金鑰和加密演算法;chacha20-poly1305 自帶完整性校驗,所以 MAC 顯示為 implicit |
KEX_ECDH_REPLY received、is known and matches |
第 4、5 步,完成金鑰交換,主機公鑰與 known_hosts 一致 |
NEWKEYS sent、NEWKEYS received |
第 6 步,從這裡開始全部加密 |
Authentications that can continue、Authenticated to |
第 7 步,伺服器允許公鑰和密碼兩種方式,最終用公鑰透過 |
Entering interactive session. |
第 8 步,開啟會話通道 |
想知道本機支援哪些演算法,用 ssh -Q kex、ssh -Q cipher;伺服器端實際生效的配置,用 root 執行 sshd -T 檢視。
公鑰認證為什麼不怕連到假伺服器
密碼認證時,客戶端把密碼本身(在加密通道里)交給伺服器。如果你在第 5 步忽略了指紋告警、連上的其實是一台冒充的機器,它就直接拿到了你的明文密碼。公鑰認證時,客戶端發出去的是用私鑰對本次會話標識做的簽名,私鑰從不離開本機;冒充者拿到的簽名只對它自己那次會話有效,拿去登入真伺服器也通不過。所以在機房這類同一網段可能存在其他租戶、存在 ARP 欺騙風險的環境裡,公鑰認證加上認真對待指紋告警,比單純依賴密碼安全得多。
SSH 連接埠是什麼意思:22 連接埠是幹嘛的
“SSH 連接埠”指伺服器上 sshd 監聽的 TCP 連接埠。22 是 IANA 分配給 SSH 的標準連接埠,客戶端不指定連接埠時就連 22;客戶端自己一側用的是系統隨機分配的臨時連接埠。SSH 只用 TCP,放行時不需要 UDP 22。
在伺服器上可以看到 sshd 在哪個連接埠監聽,以及當前有哪些 SSH 連線:
ss -tlnp | grep sshd # 監聽的位址和連接埠
ss -tnp state established '( sport = :22 )' # 當前每條 SSH 連線的客戶端位址
關於 22 連接埠,維運中常遇到的幾件事:
- 同一個連接埠承載多種功能。登入、SFTP、SCP、連接埠轉發都走 22,放行了 22 就全部能用;只想開放檔案傳輸、不想開放登入,要在 sshd 配置裡限制,而不是靠連接埠。
- 不止伺服器在用 22。交換器、路由器和伺服器 BMC 開啟 SSH 後,命令列同樣用 22 連接埠;網路裝置的 NETCONF 也跑在 SSH 上,標準連接埠是 830。
- 暴露在公網的 22 連接埠會被持續掃描和爆破。改連接埠能減少日誌裡的噪聲,但不能代替存取控制:能登入的來源要在安全組或防火牆裡限定,認證方式優先用金鑰。
- 22 連接埠通不代表 SSH 正常。
nc 203.0.113.10 22連上後應該立刻收到一行SSH-2.0-開頭的版本號;收不到,說明連接埠上跑的不是 sshd,或者中間有裝置在干擾。
SSH 和 Telnet 的區別
Telnet 是更早的遠端登入協議(RFC 854,1983 年),預設用 TCP 23 連接埠。它的問題不是老,而是從設計上就不提供任何保護:
| 對比項 | Telnet | SSH |
|---|---|---|
| 標準 | RFC 854(1983 年) | SSH-2:RFC 4251–4254(2006 年) |
| 預設連接埠 | TCP 23 | TCP 22 |
| 傳輸內容 | 明文,每個按鍵原樣傳送 | 加密,抓包只能看到版本號和演算法名稱 |
| 確認伺服器身份 | 做不到,連上的是不是真裝置無從得知 | 首次連線記下主機公鑰,以後每次比對,不符就告警 |
| 防篡改 | 沒有校驗,報文可被修改或插入 | 每個報文附帶校驗碼,途中被改動會被發現 |
| 認證方式 | 使用者名稱和密碼 | 密碼、公鑰、鍵盤互動(可接動態口令)、證書 |
| 附帶能力 | 只有終端 | SFTP、連接埠轉發、一條連線複用多個通道 |
| 自動化 | 少數工具支援 | Ansible、NETCONF 等以 SSH 為基礎 |
| 現在用在哪裡 | 不支援 SSH 的老裝置、裝置開局時臨時使用;telnet IP 連接埠 測試 TCP 連接埠是否開放 |
伺服器、網路裝置、BMC 的標準遠端管理方式 |
區別在抓包裡看得最清楚。在伺服器上分別抓一次 Telnet 和 SSH 登入,-A 引數把報文內容按文字列印:
tcpdump -i eth0 -nn -A 'tcp port 23'
tcpdump -i eth0 -nn -A 'tcp port 22'
Telnet 的輸出裡,login: 提示、你輸入的使用者名稱,以及密碼的每一個字元,都按順序出現在客戶端發往伺服器的報文裡:密碼雖然不回顯在螢幕上,但傳送的內容是原樣的。SSH 的輸出裡,能讀懂的文字只出現在最開始的幾個包:雙方的版本號,以及協商階段列出的演算法名稱,如 curve25519-sha256、ssh-ed25519、[email protected];從 NEWKEYS 之後全是無法辨認的位元組,使用者名稱和密碼都在其中。
Telnet 唯一還常用的場合,是拿 telnet 客戶端測試一個 TCP 連接埠通不通,例如 telnet 203.0.113.10 443。Windows 預設沒有安裝 Telnet 客戶端,用 Test-NetConnection 203.0.113.10 -Port 443 也能完成同樣的測試。
機房伺服器和交換器為什麼都要用 SSH
在 IDC 機房裡,遠端管理流量經過的地方比想象中多:同一個二層網段裡其他客戶的伺服器、交換器上的映象連接埠、上聯鏈路,以及維運人員在家遠端辦公時經過的公網。只要其中一個位置能看到 Telnet 流量,密碼就洩露了。而交換器、路由器和 BMC 的帳號許可權極高:一個交換器管理員密碼,影響的是這台交換器上的所有客戶;一個 BMC 帳號,可以開關機、掛載映象、看控制檯。
SSH 在這裡解決的是三件事:傳輸加密,管理流量被看到也沒有用;主機金鑰校驗,ARP 欺騙、位址被冒用時客戶端會告警並拒絕連線,Telnet 對此毫無察覺;統一的管理入口,配置下發、批次巡檢、堡壘機代理和會話錄影都以 SSH 為基礎。等級保護測評也會檢查遠端管理是否採取了防竊聽措施。
逐類裝置檢查是否已經只用 SSH:
# Linux 伺服器:sshd 實際生效的連接埠、root 登入和認證方式(需要 root 許可權)
sshd -T | grep -E '^(port|permitrootlogin|passwordauthentication|pubkeyauthentication) '
# 確認沒有程式在監聽 Telnet 的 23 連接埠
ss -tlnp | grep ':23 '
# 華為、H3C 交換器:SSH 服務狀態,以及 VTY 允許哪些協議登入
display ssh server status
display current-configuration | include protocol inbound
# 思科交換器:SSH 版本與 VTY 配置
show ip ssh
show running-config | section line vty
VTY 下出現 protocol inbound all、protocol inbound telnet(華為、H3C)或 transport input telnet ssh(思科),說明 Telnet 仍然可以登入,應改為只允許 SSH;改之前先確認 SSH 登入已經可用,避免把自己鎖在外面。
在管理系統裡怎麼落地
一個機房有成百上千台伺服器和幾十台交換器,SSH 入口分散在各台裝置上,誰登入過、執行了什麼命令很難追溯。Toplink DCIM 把這些入口收攏到瀏覽器裡:伺服器的 SSH 命令列可以和 VNC、RDP 控制檯一起在瀏覽器中開啟,無需安裝客戶端,SSH 會話全程錄影並記錄命令級日誌,管理員還能檢視某台裝置上的線上會話並踢出多餘的連線(見 IPMI 遠端管理)。交換器管理預設透過 SSH 或 Telnet 下發配置,排障時可以在瀏覽器裡開啟交換器的 SSH 終端,會話同樣錄影留痕;仍在用 Telnet 的老裝置可以先納管,再按上文逐台切換到 SSH。租用伺服器的客戶在客戶自助端維護自己的 SSH 金鑰和 API 金鑰,也能直接開啟 SSH 控制檯登入名下的機器。
常見問題
SSH 和 SSL/TLS 是一回事嗎?
不是。兩者都用非對稱金鑰協商、對稱加密傳輸,但是兩套獨立的協議:TLS 主要保護 HTTPS 等應用,靠 CA 簽發的證書證明伺服器身份;SSH 用於遠端登入和管理,預設靠客戶端首次連線時記下的主機公鑰確認身份。
SFTP 和 FTP 有什麼關係?
沒有關係。SFTP 是執行在 SSH 連線裡的檔案傳輸子系統,和登入共用 22 連接埠與同一套認證;FTP 是另一個獨立的協議,用 21 連接埠並另開資料連線,預設明文傳輸。給 FTP 加上 TLS 的叫 FTPS。
SSH 協議 1 還能用嗎?
不能。SSH-1 存在設計缺陷,早已被 SSH-2 取代,OpenSSH 7.6 起徹底移除了對它的支援。現在說的 SSH 都是 SSH-2,用 ssh -v 連線時能看到 Remote protocol version 2.0。