在 Windows 使用實體金鑰免密碼登入 SSH/SCP/SFTP
2 | 5,000 |
若對這個主題一頭霧水,以下是一些背景知識:
- 用金鑰取代密碼登入 SSH 伺服器或 SCP 傳檔的好處:免敲密碼登入超方便、金鑰安全強度比文字密碼高
從 Windows 使用金鑰免密碼登入 SSH/SFTP/SCP
Windows OpenSSH 伺服器筆記 - 實體金鑰的安全性比金鑰檔更上層樓,私鑰鎖在硬體偷不走、PIN 碼保護 + 錯三次鎖住/自動銷毀
市面上功能最齊全的實體金鑰商品首推 Yubikey,若你有電子 DIY 基礎且不嫌麻煩的話可以試試不比雞排或珍奶便宜的土砲方案
超省資安強化方案 - 比雞排便宜的自製 USB 實體金鑰 - 成熟且普遍的實體金鑰加密、簽章、登入認證機制 - GnuPG (GPG)
GPG 筆記 - 產生 ECC 金鑰及加解密檔案
GPG 整合實體金鑰筆記
先前已介紹過用實體金鑰做 GPG 加解密,這篇來介紹如何在 Windows 使用 GPG 整合 USB 實體金鑰登入 SSH 伺服器。先大致整理重點:
- GPG 軟體推薦使用 gpg4win (gpg 2.4+) 功能較齊,比 Git Bash 附的 gpg 好用。(可用 Chocolatey 安裝:
choco install -y gpg4win
) - OpenSSH (ssh 客戶端) 建議用 Win32-OpenSSH 9.2+,可直接整合 gpg4win,省事很多。(安裝
choco install -y --pre openssh
記得加 --pre 裝 Beta 版才有 9.2,否則是 8.0) - 建立 GPG ECC 金鑰時要多做一把 Authenticate 用途子金鑰供 SSH 登入使用 參考
- 設定 gpg4win 的 gpg-agent 啟用 Named Pipe 介面模擬 ssh-agent 提供登入金鑰,Win32-OpenSSH 9.2+ SSH 客戶端可從 Named Pipe 介面存取金鑰完成登入 (這是為什麼要用 gpg4win + Win32-OpenSSH 9.2+ 的原因)
以下說明操作步驟:
- 實體金鑰要拿到不同電腦使用時,要先在該主機匯入公鑰檔 詳情
gpg --import public-key.asc gpg --edit-key <key-id or username> trust # 使用指令 trust 5 = I trust ultimately # 選 5 完全信任
- 設定
%appdata%\gnupg\gpg-agent.conf
啟用 Win32-OpenSSH 整合 (啟用 Named Pipe 介面)enable-win32-openssh-support
- 查詢金鑰 Keygrip
看第三條 [A] 那把金鑰(A 代理 Authenticate,SSH 登入會用這把),本例為 EFB9FE1F12ABAAB841BA54BCD4D331CC2C4133BA,將其寫入D:\>gpg --list-secret-keys --with-keygrip gpg: checking the trustdb gpg: marginals needed: 3 completes needed: 1 trust model: pgp gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u [keyboxd] --------- sec> ed25519 2023-08-06 [SC] B7C9B8ED0F20DED189B920628203FE9C7EC51718 Keygrip = CAE7211EC194176B103FF261B03EADD712A37B65 Card serial no. = FFFE 4E523957 uid [ultimate] Jeffrey (Gnuk Token) <jeffrey@darkthread.net> ssb> cv25519 2023-08-06 [E] Keygrip = 714D6A9FA32D04EBD5E97DBEBE521CE459662BBF ssb> ed25519 2023-08-06 [A] Keygrip = EFB9FE1F12ABAAB841BA54BCD4D331CC2C4133BA
%appdata%\gnupg\sshcontrol
,告知 pgp-agent 使用這把金鑰作供 SSH 登入之用:echo EFB9FE1F12ABAAB841BA54BCD4D331CC2C4133BA > %appdata%\gnupg\sshcontrol
- 重啟 gpg-agent
D:\>gpg-connect-agent killagent /bye OK closing connection D:\>gpg-connect-agent /bye gpg-connect-agent: no running gpg-agent - starting 'C:\\Program Files (x86)\\Gpg4win\\..\\GnuPG\\bin\\gpg-agent.exe' gpg-connect-agent: waiting for the agent to come up ... (5s) gpg-connect-agent: connection to the agent established
- 檢查確認一切設定妥當,先查 Named Pipe
\\.\pipe\openssh-ssh-agent
是否建立、ssh-add -L
檢查 SSH 金鑰是否有出現 - 將上述 ssh-ed25519 AAA... 加入到 SSH 伺服器端 authorized_keys 檔案,要注意存放位置及檔案權限設定,細節請參考前文
萬事備齊,ssh 主機IP
時將會彈出 PIN 碼輸入視窗,按下確認鈕即可成功登入,之後 PIN 碼會 Cache 一段時間,這段時間登入不用再敲 PIN 碼,直接按確認鈕即可。Cache 時間預設為 1800 秒(30 分鐘內用到 SSH 金鑰則重新計算 1800 秒,最常可 Cache 住兩小時),要延長或縮短可透過 gpg-agent.conf default-cache-ttl-ssh 及 max-cache-ttl-ssh 參數調整。參考
就醬,SSH 登入金鑰被鎖進實體晶片,駭客沒法入侵偷走,即便從遠端取得控制權,不可能隔空按下確認鈕也是枉然,我得到穿上金鐘罩的安心感,讚!
註:如果想搭配 Git Bash 或 WSL 的 gpg 使用,需使用 wsl-ssh-pageant 將 Named Pipe 轉成 AF_UNIX Socket。
Comments
# by Jason Kwok
你好,我執行「ssh-add -L」顯示「The agent has no identities.」,請問是為什麼呢?
# by Jeffrey
to Jason Kwok,依相關討論 https://stackoverflow.com/q/26505980/288936 ,可能原因為未建立金鑰或權限問題,可依討論串的做法檢查看看