近期在開發過程中 ssh 連線時驗證公鑰指紋 ( public key fingerprints ),發生過兩次的衝突案例,希望在此記錄下來,以便未來回顧之用。

衝突案例

ssh 連線常用於 git 操作或是遠端連線伺服器,身份驗證可以使用”公鑰私鑰交換”或是”用戶帳密”來進行身份驗證,正好下面提到的兩個案例各有一個。

  • 案例1:
    • 某天晚上公司 MIS 幫大家換內部自建的私有 GitLab 機台,當然換的過程有完整備份,最後連線的 ip 也是相同沒有更換,但隔天大家要使用 git ssh 的方式發動遠端操作,例如 push pull …,結果失敗 🤯
  • 案例2:
    • 某天我將公司 CI 機進行更換,換成另一台硬體性能比較好的機器,一樣有做完整轉移和設定,但最後我使用終端機發動遠端連線 ssh user@192.168.ooo.xxx,結果失敗 🤯

問題原因

進行 ssh 連線有一個漏洞需要進行防範,就是中間人攻擊 ( Man-in-the-middle attack ),可以用惡意的攔截封包軟體,並且在發送資料前後進行解密和重新加密,為了保護 ssh 連線,因此在第一次連線會建立 fingerprints,下次連線時會檢查它跟這次連線是否吻合,而它就儲存在 ~/.ssh/known_hosts

想當然案例 1 或是案例 2 發生時 fingerprints 都會發生驗證錯誤,主機更換但 ip 不變 就像是仿照了一台假機器進行攻擊一樣,不過我們自己知道目前的機器是對的。

參考來源: Checking ssh public key fingerprints

解決方法

解法就是編輯 known_hosts,移除指定的連線 fingerprint 即可!
可以直接打開文件編輯,也可用下列指令!

  • 查看目前的 known_hosts

    1
    cat ~/.ssh/known_hosts
  • 移除特定 fingerprints

    1
    2
    ssh-keygen -R 192.168.ooo.xxx
    ssh-keygen -R "[192.168.ooo.xxx]:12345"

題外話: 因為筆者平常開發 iOS 習慣用 Sourcetree,所以案例 1 在移除特定 fingerprints 後,還需要到終端機進行 git clone 任一專案讓 fingerprints 重新設定完成,不然 Sourcetree 傻傻地會有奇怪的錯誤。