跳轉到

2. SSH

SSH (Secure Shell Protocol, 安全殼層協定)

SSH

SSH 是一種加密的網路傳輸協定,可在不安全的網路中提供安全的傳輸環境。
最常見用途是遠端登入系統,利用 SSH 來傳輸命令列介面和遠端執行命令。 (維基百科)

檢查 SSH 安裝版本:ssh -V


1. 機制說明

SSH 會使用一對公鑰和私鑰來驗證使用者身份,先簡單描述兩者用途。
加密算法不用深入理解,先知道金鑰就是一長串亂碼就好。


1-1. 公鑰 & 私鑰

Public Key(公鑰)

  • 用來加密資料
  • 可以公開放在遠端伺服器上
  • 存放在伺服器的 ~/.ssh/authorized_keys

Private Key(私鑰)

  • 用來解密資料
  • 存放在用戶本機,路徑通常是 ~/.ssh/id_rsa
  • 只有擁有私鑰的人才能完成解密,代表身份驗證成功

1-2. SSH 驗證流程

SSH 主要有密碼驗證和金鑰驗證兩種方式。

密碼驗證流程

這是最常見也最簡單的驗證方式,但安全性相對較低。流程如下:

  1. 客戶端發起連線
    你的電腦 (SSH Client) 向目標伺服器 (SSH Server) 的 SSH 服務埠發起TCP 連線請求。
  2. 伺服器回應
    伺服器接收到連線請求後,會回應客戶端並告知其 SSH 版本資訊。
  3. 協商加密方式
    客戶端和伺服器會協商使用哪種加密演算法、金鑰交換方法和訊息驗證碼(MAC)演法。
  4. 伺服器發送主機金鑰
    伺服器會將自己的主機金鑰 (Host Key) 發送給客戶端。
  5. 客戶端驗證主機金鑰
    • 首次連線: 如果是第一次連線到這個伺服器,客戶端會提示你是否信任這個機金鑰,並詢問是否要將其加入到你的 known_hosts 檔案中。如果你選擇信並加入,下次連線時客戶端會比對伺服器發送的主機金鑰是否與 known_hosts中記錄的一致。
    • 後續連線: 如果主機金鑰已經存在於 known_hosts 中,客戶端會比對收的金鑰是否一致。如果不一致,會發出警告,因為這可能表示發生了中間人攻擊。
  6. 伺服器請求密碼
    伺服器會要求提供與該使用者名稱對應的密碼。
  7. 客戶端發送加密後的密碼
    客戶端輸入密碼後,客戶端會使用之前協商好的加密方式將密碼加密,然後發送給伺器。
  8. 伺服器驗證密碼
    伺服器收到加密後的密碼,會使用相同的加密方式解密,然後與系統中儲存的該使用密碼(通常是經過雜湊處理的)進行比對。
  9. 驗證密碼
    如果密碼比對成功,伺服器會允許客戶端登入,並建立一個安全的 SSH 會話。
    如果密碼比對失敗,伺服器通常會拒絕登入請求,並可能限制嘗試次數以防止暴力解。


金鑰驗證流程

使用一對公鑰和私鑰來驗證使用者身份,比密碼驗證更安全。流程如下:

  1. 產生金鑰對
    使用者在自己的電腦上使用 ssh-keygen 等工具產生一對公鑰和私鑰。 私鑰必須妥善保管,絕不能洩露給他人。
  2. 上傳公鑰到伺服器
    使用者將公鑰複製到目標伺服器上特定使用者的 ~/.ssh/authorized_keys 檔案中。 每一行代表一個允許登入的公鑰。
  3. 客戶端發起連線
    你的電腦(SSH 客戶端)向目標伺服器發起連線請求。 其餘流程與密碼驗證的前幾個步驟(1-5)相同。
  4. 伺服器請求金鑰驗證
    伺服器在驗證階段會嘗試使用 authorized_keys 檔案中的公鑰來驗證客戶端。
  5. 客戶端提供私鑰資訊
    客戶端收到伺服器請求後,會使用對應的私鑰生成一個數位簽章,並將簽章發送給伺服器。 此過程可能需要你輸入私鑰的密碼(如果私鑰有設定密碼的話)。
  6. 伺服器驗證簽章
    伺服器使用儲存在 authorized_keys 檔案中對應的公鑰來驗證客戶端發送的數位簽章。 伺服器會確認這個簽章是由與其配對的私鑰產生的。
  7. 驗證金鑰
    如果簽章驗證成功,伺服器會允許客戶端登入,而無需輸入密碼。 如果簽章驗證失敗,伺服器會拒絕登入請求。

2. 實戰練習

Info

須先準備好兩台有安裝 SSH 的機台,假定 Host_A 要 SSH 進 Host_B


2-1. 確認機器資訊

在開始用 SSH 前,我們須要知道對方(Host_B)的:

  • Username : 使用 whoami 查詢。
  • Hostname:使用 hostname 查詢。
  • IP:使用 ip a 查詢。
    應該會看到類似 inet 192.168.1.150/24 的訊息,代表 IP 是 192.168.1.150

2-2. 金鑰生成

現在,Host_A 要生成金鑰。

輸入指令 ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
連按三次 enter 即可, 會產生一組金鑰:

  • 公鑰位址:~/.ssh/id_rsa.pub
  • 私鑰位址:~/.ssh/id_rsa

Info

一個 public key 可以用來 SSH 進多台主機,無須每次都生成一組新的金鑰對。
但不同 remote host 用不同的鑰匙能提高安全性。


2-3. 遠端連線

假設 Host_B 用戶名為 user , IP 位址為 192.168.1.150

第一次連線,須將公鑰複製到遠端主機:ssh-copy-id user@192.168.1.150
以後遠端連線只須輸 ssh user@192.168.1.150 即可。

Info

注意 192.168 開頭的 IP 通常都是區域網路中 router 所分配的 IP。
只有當 Client 和 Server 都在同個網域中才能互相訪問。


2-4. SSH 設定檔

  1. 建立或編輯 SSH 設定檔:sudo nano ~/.ssh/config
  2. 範例內容:

    Host myserver
    HostName 192.168.1.150
    User user
    Port 22
    IdentityFile ~/.ssh/id_rsa
    
  3. 之後只要輸入 ssh myserver 就可以登入了。

Checkpoint

  1. 在 VSCode 中設定 ssh config 並 passwordless login remote host。
    成功連線時,能夠在 VSCode 中開啟 remote host 的資料夾,在毋須輸入密碼下,修改程式.

  2. (Optional) 學習使用 mDNS。以 remote hostname 取代 IP。
    好處是可避免 DHCP 動態分配 IP 時造成每次都要重新確認 IP 的麻煩。
    參考資料:【軟體】網路設定、連線 - mDNS 設定

Checkpoint

理解 DHCP,知道每台的 IP 位址怎麼來的。
可以如何避免 DHCP 下 IP 會浮動的問題?