若對這個主題一頭霧水,以下是一些背景知識:

先前已介紹過用實體金鑰做 GPG 加解密,這篇來介紹如何在 Windows 使用 GPG 整合 USB 實體金鑰登入 SSH 伺服器。先大致整理重點:

  1. GPG 軟體推薦使用 gpg4win (gpg 2.4+) 功能較齊,比 Git Bash 附的 gpg 好用。(可用 Chocolatey 安裝:choco install -y gpg4win)
  2. OpenSSH (ssh 客戶端) 建議用 Win32-OpenSSH 9.2+,可直接整合 gpg4win,省事很多。(安裝 choco install -y --pre openssh 記得加 --pre 裝 Beta 版才有 9.2,否則是 8.0)
  3. 建立 GPG ECC 金鑰時要多做一把 Authenticate 用途子金鑰供 SSH 登入使用 參考
  4. 設定 gpg4win 的 gpg-agent 啟用 Named Pipe 介面模擬 ssh-agent 提供登入金鑰,Win32-OpenSSH 9.2+ SSH 客戶端可從 Named Pipe 介面存取金鑰完成登入 (這是為什麼要用 gpg4win + Win32-OpenSSH 9.2+ 的原因)

以下說明操作步驟:

  1. 實體金鑰要拿到不同電腦使用時,要先在該主機匯入公鑰檔 詳情
    gpg --import public-key.asc
    gpg --edit-key <key-id or username>
    trust # 使用指令 trust
    5 = I trust ultimately # 選 5 完全信任
    
  2. 設定 %appdata%\gnupg\gpg-agent.conf 啟用 Win32-OpenSSH 整合 (啟用 Named Pipe 介面)
    enable-win32-openssh-support
    
  3. 查詢金鑰 Keygrip
     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
    
    看第三條 [A] 那把金鑰(A 代理 Authenticate,SSH 登入會用這把),本例為 EFB9FE1F12ABAAB841BA54BCD4D331CC2C4133BA,將其寫入 %appdata%\gnupg\sshcontrol,告知 pgp-agent 使用這把金鑰作供 SSH 登入之用:
    echo EFB9FE1F12ABAAB841BA54BCD4D331CC2C4133BA > %appdata%\gnupg\sshcontrol
    
  4. 重啟 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    
    
  5. 檢查確認一切設定妥當,先查 Named Pipe \\.\pipe\openssh-ssh-agent 是否建立、ssh-add -L 檢查 SSH 金鑰是否有出現
  6. 將上述 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 登入展示

就醬,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 ,可能原因為未建立金鑰或權限問題,可依討論串的做法檢查看看

Post a comment