SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

什麼是 SSH?運作方式、port 22 與登入驗證

SSH 是連線至遠端伺服器的加密通道,本文說明用戶端與伺服器模型、port 22、host key 指紋,以及金鑰與密碼登入的差異。

什麼是 SSH?

SSH(secure shell)是一種協定,可讓您登入其他位置的電腦,並透過加密連線在該電腦上執行命令。您輸入的內容會傳送至遠端機器,執行結果會傳回來;中間監看網路流量的人無法讀取其中任何內容。租用的 Linux 伺服器沒有連接螢幕與鍵盤,因此 SSH 是使用這類機器的基本方式。

這個名稱包含兩個概念。SSH 是協定,定義於 RFC 4251 至 RFC 4254。OpenSSH 是實作此協定的程式,幾乎所有 Linux 伺服器與筆記型電腦實際執行的都是它。當有人說「SSH 連入伺服器」時,指的是其電腦上的用戶端程式 ssh 與另一端伺服器上的伺服器程式 sshd 通訊。

SSH 用來取代的問題

遠端登入的歷史比 SSH 更久。Telnet 會對 port 23 建立未加密的 TCP 連線,並將每個位元組原樣送出,包括你的密碼。任何能看到網路流量的人都能讀取這些內容,例如與你位於同一辦公室網路的人員,或路徑上任一台路由器的操作人員。rlogin 系列也有相同的弱點,而且會依名稱信任用戶端機器。這代表它信任網路所宣告的名稱,而不驗證該名稱是否正確。

Tatu Ylönen 在 1995 年於 Helsinki University of Technology 撰寫了第一個 SSH。起因是大學網路遭到密碼竊聽攻擊。這項設計保留 Telnet 的實用部分,也就是終端機與遠端 shell 之間的位元組串流,並加入 Telnet 無法處理的兩項功能:加密串流,以及證明連線另一端的伺服器確實是你要連線的伺服器。

第二部分很容易被忽略,但它是 SSH 功能的一半。單靠加密並不足以保護你。中間的機器可以接受你的連線,以完整方式加密資料,讀取你傳送的所有內容,再將資料轉送給真正的伺服器。SSH 會為每台伺服器建立稱為 host key 的永久身分,並在每次連線時進行驗證,以阻擋這種攻擊。

用戶端與伺服器模型的運作方式

這裡有兩個程式。伺服器上的 sshd 會持續執行並等待連線。您的電腦則由 ssh 建立連線。這兩個程式彼此獨立,也各自使用不同的設定檔。混淆兩者,是修改設定後沒有生效的最常見原因。

  • 伺服器讀取 /etc/ssh/sshd_config。您可以在這裡停用密碼登入,以及設定監聽連接埠。
  • 用戶端先讀取 /etc/ssh/ssh_config 取得系統預設值,再讀取 ~/.ssh/config 取得您個別設定的主機選項。

在 Debian 和 Ubuntu 上,服務單元名稱是 ssh。在 RHEL、Rocky 和 Fedora 上,服務單元名稱是 sshd。近期的 Ubuntu 版本會以 socket activation 模式安裝,因此即使主機完全可以連線,systemctl status ssh 仍可能回報 inactive (dead),因為實際負責監聽的是 ssh.socket,而且它會在需要時啟動服務。

用戶端不一定要使用 OpenSSH。Windows 上的 PuTTY、手機上的 Termius,以及編輯器內建的遠端支援功能,都能透過相同的通訊協定連線至相同的 sshd。Windows 10 和 11 也內建 OpenSSH 用戶端,因此 ssh you@server 可直接在 PowerShell 中運作,無須安裝任何元件。

為什麼 SSH 使用 22 埠?

埠號是用來告訴 kernel 傳入連線應交給哪個監聽中的程式;Linux 中的埠號對所有服務的運作方式都相同。SSH 使用 22 埠,是因為 IANA 在 1995 年將它指派給 SSH。Ylönen 申請的是一個未使用的號碼,位置正好接近 SSH 設計用來取代的通訊協定:21 是 FTP,23 是 telnet,而 22 當時尚未使用。

因為 22 是預設埠,所有工具都會假設使用它。Git remote、備份腳本和供應商的控制面板都會先嘗試 22。網際網路上的自動掃描器也一樣。啟用密碼登入的新伺服器在開機後幾分鐘內,便會在 /var/log/auth.log 收到類似以下的內容:

Failed password for invalid user admin from 203.0.113.55 port 43122 ssh2

這類流量會持續出現,而且不是專門針對你的伺服器。將 sshd 改為 2222 埠,可以移除大多數這些訊息,因為掃描器是在整個網際網路上掃描 22 埠,而不是研究你的伺服器。對真正注意到該伺服器的人而言,這不會讓主機更難遭到入侵。應將變更埠號視為降低雜訊的方法,除此之外不要過度解讀。

即使尚未登入,你也可以查看伺服器如何回應:

nc 203.0.113.10 22

在 Ubuntu 24.04 上,這會輸出接近 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13 的內容。banner 會以明文傳送,因為此時尚未建立加密連線;雙方必須先協議通訊協定版本。按下 Ctrl+C 關閉連線。

連線時網路線路上會發生什麼事

以下是某個 ssh you@server 在顯示提示字元前會執行的流程。

  1. 用戶端將主機名稱解析為 IP 位址,然後對埠 22 開啟 TCP 連線。
  2. 雙方以明文傳送版本標頭。
  3. 雙方傳送所支援的演算法清單:金鑰交換、加密、訊息驗證與壓縮。此時仍是明文。雙方都支援的最強選項會獲選。
  4. 執行金鑰交換。目前的 OpenSSH 偏好使用 curve25519-sha256。最後,兩端會持有相同的共用密鑰,但該密鑰從未經過網路傳送。因此,即使有人錄下整段通訊內容,事後也無法推算出該密鑰。
  5. 伺服器使用其主機私密金鑰對交換結果簽章。用戶端會根據已儲存的主機公開金鑰驗證簽章。這個步驟可防止中間的機器冒充伺服器。
  6. 開始加密。目前的 OpenSSH 預設使用 chacha20-poly1305@openssh.com 加密器。
  7. 到這時,用戶端才會使用密碼或金鑰驗證你的身分。你的使用者名稱與密碼會在加密通道內傳送。
  8. 用戶端開啟通道,並要求啟動 shell。

這份清單中的順序,就是 SSH 與 telnet 的完整差異。驗證會在通道加密且伺服器完成身分驗證後才進行,因此密碼不會有任何時刻以明文形式出現在網路線路上。

監看網路的人仍能得知部分資訊。他們看得到你的 IP 位址、伺服器的 IP 位址、埠 22、雙方的明文版本標頭,以及每個封包的傳送時間與大致大小。他們看不到你的使用者名稱、密碼、命令或命令輸出。第 1 步中的主機名稱查詢不屬於 SSH,通常也不是私密的。因此,解析伺服器名稱的 DNS 查詢 可能會透露你即將連線的機器,即使工作階段本身受到加密保護。

主機金鑰與首次連線時的指紋提示

安裝 openssh-server 時,會為本機產生主機金鑰組,並將其寫入 /etc/ssh/,例如 ssh_host_ed25519_keyssh_host_ed25519_key.pub。私密金鑰不會離開伺服器。公開金鑰是伺服器的身分,步驟 5 會根據它驗證簽章。

首次連線到新伺服器時,您的用戶端沒有可供比對的金鑰,因此會詢問:

The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:E9nVQ5Sm2oQ3nGm5Zf1tOaU7Xh0k2p8bWc4dLrTvYxA.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

指紋是主機公開金鑰的 SHA256 雜湊值,以 base64 顯示,因此長度足以讓人目視比對。輸入 yes 會將該金鑰寫入您自己電腦上的 ~/.ssh/known_hosts。之後每次連線到相同位址時,都會將伺服器提供的金鑰與儲存的金鑰比對。兩者相符時,不會顯示任何訊息,您會直接回到提示字元。

這種模式稱為首次使用時信任(trust on first use),您應清楚了解它的代價。首次連線是唯一未受保護的時刻,因為您正在接受從未見過的金鑰。若要消除這項風險,請透過其他管道取得指紋並進行比對。大多數供應商會在 Web 主控台顯示的開機輸出中列出指紋,您也可以直接在伺服器上顯示:

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

這會顯示與提示中相同的 SHA256: 字串。提示中的 [fingerprint] 選項正是用於此目的:貼上您預期的指紋,只有在與伺服器提供的指紋相符時,用戶端才會繼續。

在 Debian 和 Ubuntu 上,known_hosts 預設會進行雜湊處理,因此檔案中的每行會以 |1| 開頭,而不是可讀的主機名稱。執行 ssh-keygen -F 203.0.113.10 可尋找某部主機的項目。

為什麼 SSH 會顯示主機金鑰已變更?

你遲早會看到這段很長的訊息:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

訊息最後會顯示 Host key verification failed.,而用戶端拒絕連線。它也會顯示 Password authentication is disabled to avoid man-in-the-middle attacks.,因為禁止你將密碼輸入未知機器,正是這項檢查要避免的風險。

這段訊息看起來像緊急事件,但大多數情況並非如此。常見原因如下:

  • 你重建或重新安裝了伺服器,因此 sshd 在第一次開機時產生了新的主機金鑰。這是最常見的原因。
  • 你刪除了一台 VPS 並建立另一台,而供應商將原本的 IP 位址指派給新機器。
  • 你是透過 forward 或 load balancer 連線,而它現在將請求轉送到另一台後端機器。
  • 確實有其他來源攔截了這個連線。

清除任何項目之前,先判斷實際原因。如果你在 10 分鐘前重新安裝了這台機器,原因很明顯。如果你這端沒有任何變更,請停止操作並進行調查,因為這項警告正發揮其應有的檢查作用。確認原因後,移除過時的項目,再重新連線:

ssh-keygen -R 203.0.113.10

下一次連線時會再次顯示指紋提示,讓你有機會將指紋與供應商主控台中的內容重新比對。

密碼登入與金鑰登入

密碼驗證會在已加密的通道中傳送您的密碼,sshd 通常會透過 PAM(可插拔驗證模組)向帳戶資料庫核對密碼。這不需要事前準備,因此服務供應商可以只提供 root 密碼,就交付一台新的伺服器給您。

弱點不在加密本身,而在於密碼是較短的機密資料。您每次登入都會將密碼傳送給伺服器,而埠 22 全天候遭到不會疲倦的機器猜測密碼。

公開金鑰驗證的運作方式不同。您會在自己的電腦上建立金鑰組。公開金鑰放入伺服器上您帳戶中的 ~/.ssh/authorized_keys。私密金鑰留在您的筆記型電腦上,永遠不會傳送出去。登入時,client 會對一段包含金鑰交換所得工作階段識別碼的資料簽章,伺服器則使用已持有的公開金鑰驗證該簽章。由於簽署的資料與這個工作階段綁定,擷取到的簽章無法用於其他用途。

請注意方向。弄反很常見,而且會造成風險:公開金鑰放在伺服器上,私密金鑰留在您手中。複製到伺服器上的私密金鑰,就不再是您能信任的私密金鑰。

金鑰登入也有自己的故障模式。當檔案權限過於寬鬆時,sshd 會忽略金鑰,並在伺服器日誌中記錄原因:

Authentication refused: bad ownership or modes for directory /home/ubuntu/.ssh

client 只會告訴您 Permission denied (publickey)。這是十幾種不同原因共用的相同訊息,因此在您被拒於門外前,值得先學會正確解讀 publickey 錯誤。建立金鑰、使用 passphrase 保護金鑰,以及將金鑰載入 agent 的實務操作,請參閱SSH 金鑰管理;在不讓自己失去存取權的情況下關閉密碼登入,請參閱強化 VPS 上的 SSH

SFTP、scp 與連接埠轉送共用同一個連線

這個概念能幫助你理解 SSH 的其他功能。驗證會建立加密連線,而該連線可以同時承載多個彼此獨立的通道。Shell 只是其中一種通道。

  • 遠端 shell。ssh you@server 會開啟工作階段通道,並要求啟動互動式 shell。
  • 單一命令。ssh you@server uptime 會開啟通道、執行一個命令、輸出結果,然後結束。
  • SFTP。用戶端會要求 sshd 啟動其 sftp 子系統,檔案傳輸則在同一個連線中進行。SFTP 是透過 SSH 傳輸的檔案傳輸協定,設計上與 FTP 無關。將加密功能加入 FTP 的協定稱為 FTPS,與 SFTP 無關。
  • scp。使用相同的登入方式複製檔案。自 2022 年發布 OpenSSH 9.0 起,scp 預設會在底層使用 SFTP 協定。
  • 連接埠轉送。ssh -L 8080:localhost:80 you@server 會將筆電上的連接埠 8080 轉成通往伺服器連接埠 80 的入口,並透過加密連線傳輸。-R 會朝相反方向轉送,而 -D 1080 會將工作階段轉成 SOCKS proxy。
  • Git。像 git@github.com:user/repo.git 這樣的遠端端點,實際上是 SSH 登入;遠端端執行的是命令處理程式,而不是 shell。
  • rsync 與 Ansible 也是 SSH 用戶端。它們會開啟通道、執行操作,然後讀回輸出。

清單中的每個項目都使用相同的連接埠、相同的主機金鑰檢查,以及相同的憑證。這就是為什麼只要設定一次金鑰驗證,便能立即在這些工具中重複使用。也因此,同一個 ~/.ssh/config 檔案不僅能縮短登入流程,還能在你從一台筆電管理多台 Linux 伺服器時擴充使用。

SSH 不會處理的事項

  • SSH 不會讓伺服器自動變得安全。SSH 只保護通往入口的連線。入口仍然存在,仍會有人持續嘗試登入。使用 fail2ban 封鎖重複登入嘗試 可處理這類嘗試的數量,而僅允許使用金鑰驗證則能移除攻擊者試圖猜測的項目。
  • SSH 無法防範來自自己電腦的風險。任何能存取你筆記型電腦的人,都能取得你的私密金鑰與已載入的 agent。
  • SSH 不會隱藏你正在使用 SSH。連接埠號碼與明文版本標頭都會表明這一點。
  • SSH 不涵蓋連線建立前發生的事項。名稱查詢,以及你決定信任哪個位址,都會先於連線建立。

接下來的方向

如果你現在已在供應商主控台中開啟一台新伺服器,操作順序是固定的。先登入,建立一般使用者,安裝你的 cryptographic key,然後關閉容易被利用的登入途徑。新 VPS 的前 10 分鐘會從頭到尾說明這個順序;如果你還不熟悉相關用語,VPS 實際上是什麼則會補充底層機器的運作方式。接著應依序閱讀金鑰與強化安全性這兩篇文章。

FAQ

SSH 代表什麼?

SSH 代表 secure shell。這是一種用於登入遠端電腦,並透過加密連線在遠端執行命令的通訊協定,定義於 RFC 4251 至 RFC 4254。OpenSSH 是幾乎所有人使用的實作:您電腦上的 ssh 用戶端,以及遠端電腦上的 sshd 伺服器。它取代了 telnet;telnet 會以明文在網路上傳送包括密碼在內的所有內容。

SSH 為什麼使用 22 埠?

IANA 在 1995 年將 22 埠指派給 SSH,位置鄰近 FTP 使用的 21 埠與 telnet 使用的 23 埠;SSH 的設計目的就是取代這些通訊協定。沒有任何因素強制使用這個編號:在伺服器上,Port 會在 /etc/ssh/sshd_config 中變更連接埠;在用戶端上,ssh -p 可選擇其他連接埠。由於 22 是預設值,自動化掃描器會持續連線嘗試,因此新伺服器的 /var/log/auth.log 很快就會充滿 Failed password for invalid user 行。變更連接埠可減少這些雜訊,但不會提供實質保護。

SSH 警告主機金鑰已變更時,應該怎麼做?

先找出原因,再清除任何內容。通常原因沒有安全疑慮:伺服器已重新建置,因此 sshd 產生了新的主機金鑰;或是另一台新機器取得了原本的 IP 位址。如果您確認機器已重新建置,請執行 ssh-keygen -R <host> 移除已儲存的金鑰,重新連線,並將畫面顯示的指紋與供應商主控台回報的指紋比對。如果您這邊沒有任何變更,請勿連線,也不要輸入密碼。OpenSSH 在這種狀態下已拒絕密碼驗證,原因正是為了防止此類風險。

SFTP 和 scp 與 SSH 不同嗎?

它們都是在 SSH 之上運作。完成驗證後,SSH 連線可以承載多個通道,而 shell 只是其中之一。SFTP 是檔案傳輸通訊協定,透過同一連線使用 sshdsftp 子系統;自 OpenSSH 9.0 起,scp 底層使用的也是 SFTP 通訊協定。連接埠轉送和透過 SSH 使用 Git 也都是同一連線上的通道。它們使用相同的連接埠、相同的主機金鑰檢查方式,以及相同的登入資訊。請注意,SFTP 不是在 FTP 上加入加密功能;具備該功能的協定稱為 FTPS,兩者是不同的通訊協定。

金鑰驗證真的比密碼更好嗎?

是,對任何可從網際網路連線的伺服器而言都是如此。密碼是短期密密碼,每次登入時都必須提供給伺服器;自動化用戶端也會持續嘗試猜測 22 埠上的登入資訊。使用金鑰組時,私密金鑰不會離開您的電腦:用戶端會對與目前工作階段相關的資料簽署,伺服器則會使用 ~/.ssh/authorized_keys 中的公開金鑰驗證該簽章。錄製下來的簽章無法重放到另一台伺服器。請使用複雜密碼保護私密金鑰,因為沒有複雜密碼的金鑰檔案,任何複製到該檔案的人都能直接用它登入。