在 SSH 的設定檔 (`~/.ssh/config`) 中,調整加密演算法和金鑰管理是非常重要的資安實踐。
以下為您詳細說明這三個關鍵配置項目:
---
### 1. `HostkeyAlgorithms` (主機金鑰演算法)
**作用:** 定義 SSH 用戶端(Client)在連線到伺服器時,**願意接受哪些演算法來驗證伺服器的身分**。
* **為什麼要設定它?**
* **安全性:** 為了避免中間人攻擊(MITM),你需要確保伺服器使用的是強健的加密演算法。
* **相容性:** 舊的伺服器可能只支援過時的演算法(如 `ssh-rsa`),而新的伺服器則推薦使用 `ssh-ed25519`。
* **建議配置:**
```text
Host *
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256
```
* **說明:** 上述設定優先使用最安全的 Ed25519,若有需要連線舊伺服器,才視情況加上 `ssh-rsa`(不建議,除非必要)。
---
### 2. `PubkeyAcceptedAlgorithms` (公開金鑰接受演算法)
**作用:** 定義在進行「公開金鑰驗證」(Public Key Authentication)時,用戶端**允許使用哪些演算法來進行簽章**。
* **為什麼要設定它?**
* 這控制的是「客戶端證明自己是誰」的過程。
* 自從 OpenSSH 8.8+ 以後,預設禁用了 `ssh-rsa` (SHA-1)。如果你的伺服器很舊,還在用舊版的 RSA 金鑰,你可能需要手動把它加回來(雖然這不安全)。
* **建議配置:**
```text
Host *
PubkeyAcceptedAlgorithms ssh-ed25519,ecdsa-sha2-nistp256,rsa-sha2-512,rsa-sha2-256
```
* **說明:** 這包含了現代建議的演算法。如果遇到「No matching host key type found」錯誤,通常就是這裡與伺服器不匹配。
---
### 3. `IdentityFile` (身分金鑰檔案)
**作用:** 指定在連線到該主機時,**要使用哪一個私鑰檔案(Private Key)進行驗證**。
* **詳細用法:**
如果你有多個不同的專案(例如 GitHub 一個、公司伺服器一個、個人伺服器一個),你可以為每個 Host 設定不同的 IdentityFile。
* **範例設定:**
```text
# GitHub 的設定
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github
# 公司伺服器設定
Host office-server
HostName 192.168.1.100
User admin
IdentityFile ~/.ssh/id_ed25519_office
```
* **提示:**
* `IdentitiesOnly yes`:強烈建議在設定檔中加入這一行。如果不加,SSH 會嘗試把所有預設的金鑰(`id_rsa`, `id_ed25519` 等)都送給伺服器試一遍,這有時會導致「嘗試過多金鑰而被伺服器拒絕連線」的問題。
---
### 總結建議的 `.ssh/config` 範本
您可以將此內容放入 `~/.ssh/config`:
```text
# 全域預設設定
Host *
# 僅使用指定的金鑰檔案,避免嘗試所有金鑰
IdentitiesOnly yes
# 加強安全性:僅接受安全的演算法
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519,ecdsa-sha2-nistp256
PubkeyAcceptedAlgorithms ssh-ed25519,ecdsa-sha2-nistp256,rsa-sha2-512,rsa-sha2-256
# 針對特定伺服器的自定義
Host my-server
HostName 123.45.67.89
User username
IdentityFile ~/.ssh/id_ed25519_custom
# 如果這台伺服器真的很舊,才在下面這行強制加入 ssh-rsa (不推薦)
# PubkeyAcceptedAlgorithms +ssh-rsa
```
### 小撇步:
* **檢查你的金鑰:** 盡量使用 `ed25519` 演算法生成金鑰,指令為:`ssh-keygen -t ed25519`。
* **除錯:** 如果連線失敗,可以使用 `ssh -v my-server` 查看詳細的連線握手過程,這能告訴你到底是哪一種演算法不匹配。
---
在 Azure DevOps (ADO) 使用 SSH 拉取程式碼時出現 `fatal` 錯誤,確實**很大機率與 SSH 的演算法(Algorithm)不相容有關**,特別是當你使用的是較新版本的 OpenSSH (8.8 以上) 時。
以下是詳細的原因分析與解決步驟:
---
### 1. 為什麼會發生這個問題?
早期的 OpenSSH 預設支援較舊的加密演算法(如 `ssh-rsa`,即 SHA-1 哈希算法)。然而,由於安全性考量,現代版本的 OpenSSH 已經棄用了這些弱加密演算法。
如果你的 Azure DevOps 帳號配置的 SSH Key 是使用舊格式,或者你的客戶端 OpenSSH 版本太新,強制要求更強的加密演算法(如 `rsa-sha2-256` 或 `rsa-sha2-512`),而兩端無法達成共識,就會導致連線失敗,錯誤訊息通常如下:
* `fatal: Could not read from remote repository.`
* `no matching host key type found` 或 `no matching key exchange method found`
---
### 2. 如何確認是否為演算法問題?
你可以透過手動執行以下指令來進行測試:
```bash
ssh -vT git@ssh.dev.azure.com
```
* `-v` 會顯示詳細的除錯訊息(Verbose)。
* 如果在輸出訊息中看到 **"no matching host key type found"**,那幾乎可以確定就是演算法不相容的問題。
---
### 3. 如何調整 Git / SSH 設定檔?
你需要修改本地電腦的 `~/.ssh/config` 檔案(Windows 路徑通常在 `C:\Users\你的使用者名稱\.ssh\config`)。
#### 步驟:
1. 開啟或建立 `~/.ssh/config` 檔案。
2. 加入以下設定,明確告訴 SSH 客戶端該如何連線到 Azure DevOps:
```text
Host ssh.dev.azure.com
HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa
```
#### 參數說明:
* **`Host ssh.dev.azure.com`**: 確保這些設定只針對 Azure DevOps 生效,不會影響連線到 GitHub 或其他伺服器。
* **`HostkeyAlgorithms +ssh-rsa`**: 允許使用舊版的 `ssh-rsa` 主機金鑰。
* **`PubkeyAcceptedAlgorithms +ssh-rsa`**: 允許使用舊版的 `ssh-rsa` 公鑰演算法。
---
### 4. 更好的解法:建議改用 ED25519
上述做法是透過「降低安全性」來解決問題。**最根本且推薦的做法是生成一組使用 `Ed25519` 演算法的新金鑰**,因為現代的 Azure DevOps 已經完全支援這種更安全且快速的演算法。
**操作步驟:**
1. **產生新金鑰:**
```bash
ssh-keygen -t ed25519 -C "你的 email@example.com"
```
(這會在 `~/.ssh/` 下產生 `id_ed25519` 與 `id_ed25519.pub`)
2. **複製公鑰內容:**
```bash
cat ~/.ssh/id_ed25519.pub
```
3. **加入 Azure DevOps:**
* 登入 [Azure DevOps](https://dev.azure.com/)。
* 點選右上角的頭像 -> **SSH public keys**。
* 點選 **+ New Key**,將剛剛複製的公鑰貼上去並儲存。
4. **測試連線:**
```bash
ssh -T git@ssh.dev.azure.com
```
如果成功,你會看到類似 `remote: Shell access is not supported...` 的歡迎訊息。
---
### 總結建議
1. **立即解法:** 修改 `~/.ssh/config` 加入 `+ssh-rsa` 設定(適用於急需工作的情況)。
2. **長遠解法:** 生成 `ed25519` 金鑰並更新到 Azure DevOps 後台(推薦,安全性最高)。
**注意:** 如果你的系統非常老舊(例如非常舊的 Linux 發行版),可能連 `ed25519` 都不支援,那才必須考慮升級系統套件。但針對大多數 Windows/macOS/現代 Linux 使用者,採用 `ed25519` 是最佳實踐。