實驗環境:Ubuntu18.04 遠程伺服器 + WSL 2 本機
測評說明#
-
-
在測過程中,你需要用到的數據在這裡:測評服務的公鑰
-
附加:免密登錄的本質到底是什麼?
最終效果#
【在本地測試】
-
-
ssh 主機名,已可免密登錄
-
又是綠 :)
實現過程#
兩步走⭐#
【生成密鑰對👉複製公鑰】
- ① 在本地 WSL 2 生成公私鑰 [.pub 後綴的為公鑰],這裡選擇 RSA 加密算法
ssh-keygen -t rsa
-
- 可使用 ssh-keygen --help 查看密鑰類型等各種信息
- 一般不需要設置 passphrase [用於加密私鑰],除非你希望每次免密登錄時輸密碼
- ② 將公鑰配置到遠程伺服器上,一條命令即可
ssh-copy-id ten
-
- 這裡使用的 ten 是遠程伺服器的別名(用戶名默認為本地用戶,否則可使用 hz@ten 的方式),具體設置方法可參考《Linux 入門及使用》筆記匯總 ——5 基本系統 —— 附加知識點:使用 ssh 綽號登錄雲主機
- 或者可以使用
ssh-copy-id 用戶名@IP
的方式,下文中的 ten 和用戶名 @IP 等價
🔚至此,實現了免密登錄,連接雲主機 ten 進行測試
ssh ten
ssh-copy-id 的細分步驟#
如果想自己手工實現 ssh-copy-id 的效果,可參考下列步驟:
- 複製本地公鑰到遠程伺服器的家目錄
scp ~/.ssh/id_rsa.pub ten:
- ssh 登錄到遠程伺服器的家目錄,將公鑰的內容追加到密鑰的配置文件後
cat id_rsa.pub >> .ssh/authorized_keys
rm id_rsa.pub # 可刪
-
- authorized_keys 可以存儲多個不同公鑰,每一行對應一個
- 如果沒有.ssh 目錄和 authorized_key 文件,自行創建即可
- 【關鍵】是兩者的【權限】,要特定設置一下:讓.ssh 目錄只有所屬者有全部權限,讓 authorized_keys 文件只有所屬者有讀寫權限;否則免密登錄難以成功
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
🔚至此,也實現了免密登錄
【權限要求】
- 可參考 man sshd
-
- 安全起見,如果權限設置不符合要求,將無法使用公鑰文件
-
附加說明#
- 確認本機和遠程伺服器的 /etc/ssh/sshd_config 裡的 PubkeyAuthentication 設為 yes,修改完需要重啟 sshd 服務:systemctl restart sshd.service
- 想免密登錄遠程伺服器的哪個用戶,就將公鑰放在那個用戶的【家目錄】相應位置
免密登錄的本質#
流程⭐#
- 本地發起 SSH 連接,發送本機公鑰
- 遠程伺服器拿到公鑰後,與本地的公鑰做比對
- 如果一致,伺服器會用公鑰加密 “隨機字符串”,發回本地
- 本地拿出私鑰解密 “隨機字符串”,將結果再發給伺服器
- 如果一致,連接建立
❗ 參考SSH 免密登錄原理與實現—— 掘金
【這裡提到了密碼登錄和免密登錄兩種方式的具體流程】
- 密碼登錄
-
- 利用遠程伺服器的公鑰給密碼加密
-
- 免密登錄
-
- 傳輸過程都不會暴露私鑰
-
密碼登錄方式比免密登錄方式簡單,即密碼登錄在連接時更快一些
但是免密登錄則更加安全:
- ① 密碼更容易被識破
- ② 參考文章中提到免密登錄不存在 “中間人攻擊” 的風險,我並不完全認同
- 兩者首先都是靠.ssh/known_hosts 來識別機器
- 而免密登錄多一次公鑰的匹配,免密登錄更安全
- 【注意】但這是在本地公鑰沒有被中間人盜取的情況下
附加說明#
- ssh -v ten:可以看到更詳細的過程
- 網上有一張廣為流傳的圖,但存在細節錯誤,如下:
-
- 請求信息不是用戶名和 IP❌,而是本地的公鑰
- 公鑰裡並沒有存儲 IP [否則會帶來隱患],存儲的是本機的用戶名和主機名
- 可嘗試將本地或遠程伺服器公鑰中的用戶信息 [用戶名和主機名] 刪去,仍可免密 SSH 連接
- 可見,遠程伺服器驗證的是公鑰字符串本身!
-
思考點#
- 第一次登錄雲主機顯示的身份驗證是什麼?
-
- 什麼是 ECDSA key fingerprint?來自遠程伺服器的密鑰指紋,每台安裝了 ssh 的機器都有自己的指紋
- 輸入 yes 後,會將指紋相應信息存入本地的.ssh/known_hosts,當下次連接若存在偽裝機,可產生警覺
- 如果首次連接就有偽裝機 [中間人] 攻擊,那麼恭喜你中奖了
- 參考驗證遠程主機 SSH 指紋—— 博客
-
附加#
-
ssh-copy-id 的使用
- 直接將本機本用戶的公鑰複製到遠程機器家目錄 /.ssh 下的 authorized_keys 文件中
-
- 更簡單、更直接,可指定具體公鑰、特定端口等
-
可使用 man sshd_config 查看 sshd_config 的具體配置說明
-
⭐禁用密碼登錄,修改 /etc/ssh/sshd_config 裡 PasswordAuthentication 為 no
-
- 重啟 sshd 服務:systemctl restart sshd.service,生效
-
-
公鑰的位置可以通過 /etc/ssh/sshd_config 裡 AuthorizedKeysFile 自行設置
-
- 默認在用戶家目錄對應位置找公鑰
-
-
ChanllengeResponseAuthentication 是什麼?
-
ChallengeResponseAuthentication no
# 允許任何類型的密碼認證!所以,任何 login.conf 規定的認證方式,均可適用!
# 但目前我們比較喜歡使用 PAM 模塊幫忙管理認證,因此這個選項可以設定為 no 喔!
參考資料#
- SSH Login Without a Password——howchoo
- ssh 免密登錄踩坑及解決—— 碼農家園
- 裡面提到 authorized_keys 的權限設為 644,因為文件所屬者是 root;也可以修改文件所屬者 [個人認為後者更安全]
- 文字接口聯機伺服器:SSH 伺服器—— 鳥哥的 Linux 私房菜
- ssh 修改登錄端口禁止密碼登錄並免密登錄—— 簡書
- SSH 用公鑰驗證可以阻止中間人攻擊麼?—— 知乎
- 不能,是通過首次連接時的 known_hosts 驗證避免的