用 YubiKey FIDO2 Bio 玩轉 SSH:Resident Key 與 Git 簽章實作指南

使用 YubiKey FIDO2 Bio 建立 SSH resident key、啟用 verify-required 生物辨識登入,並設定 Git SSH 簽章與 allowed_signers 的完整流程。

前情提要:我大約在 2024 年購入了一隻 YubiKey,評價與具體經過請參見 實體金鑰初體驗

這段期間每當我使用 YubiKey 時,就會深刻反省自己亂花錢。為了亡羊補牢,我問了 AI 實體金鑰是否有其他應用。

由於我買的是 YubiKey Bio FIDO Edition,所以只有 FIDO2 與 U2F 兩種功能,不像 YubiKey 5 系列那麼豐富。

YubiKey 不同系列的比較可以參考:https://www.yubico.com/tw/store/compare/

在共用電腦上使用包含金鑰的 USB 雖然方便,但極度不安全。這時我們實體金鑰就能在保有安全性的前提下,也有便利性。

前置準備

  • 安裝 YubiKey Manager(ykman)或是 Yubico Authenticator(GUI)
  • 確認 OpenSSH 版本支援 FIDO/U2F(ssh -V)。若 ssh-keygen -t ed25519-sk 出現「security key support not enabled」,請改用 Windows 的 OpenSSH 或更新到支援 FIDO 的版本。

生成金鑰

我們可以利用 ykmanYubico Authenticator(GUI) 來管理 credentials。

1
ykman fido credentials list

像 YubiKey Bio FIDO Edition 能儲存 25 個 discoverable credentials(網站的 passkey 與 SSH 的 resident key 都算在額度內)。

確認沒有其他 SSH 金鑰後,在 YubiKey 內產生 SSH 金鑰(加上 resident 與 verify-required):

1
ssh-keygen -t ed25519-sk -O resident -O verify-required

如需從 YubiKey 將 resident key 寫回至本機 ~/.ssh/(仍需 YubiKey 才能使用):

1
ssh-keygen -K

使用金鑰

暫時使用(加入 ssh-agent)

  • Windows PowerShell:
1
2
3
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
ssh-add "$env:USERPROFILE\.ssh\id_ed25519_sk_rk"
  • macOS/Linux:
1
2
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519_sk_rk

verify-required

verify-required 就是要求使用者不只需要碰一下 YubiKey,還要求輸入 PIN,而這部分就是 Bio 版本有優勢的部分。Bio 只需要摸一下,就能同時驗證,因此不需要輸入 PIN。

有關 ssh server 的設定跟一般的方法差不多:

1
2
sudo nano ~/.ssh/authorized_keys
sudo service ssh restart

只是需要在 ~/.ssh/authorized_keys 的地方,將公鑰設定的最前面插入 verify-required

1
verify-required sk-ssh-ed25519@openssh.com AAAA...

可搭配其他一般 key options,如 restrictfrom= 等以提高安全性。

Git Signing

使用 YubiKey 內的 SSH 金鑰做 Auth 不贅述;若用於簽章,需設定 allowed_signers。

驗證 GitHub Auth(可選):

1
ssh -T git@github.com

GitHub 設定

https://github.com/settings/keys 新增 ~/.ssh/id_ed25519_sk_rk.pub 於 SSH Signing keys。

本地 git 設定

1
2
3
git config --global gpg.format ssh
git config --global commit.gpgsign true
git config --global user.signingkey "~/.ssh/id_ed25519_sk_rk.pub"

建立 allowed_signers(Principal 建議用你的 Git email,GitHub 大概率是用 userid+username@users.noreply.github.com):

1
2
echo "$(git config --get user.email) $(cat ~/.ssh/id_ed25519_sk.pub)" >> ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile "~/.ssh/allowed_signers"

測試

1
2
3
git commit --allow-empty -m "測試簽章"
git push
git log -1 --show-signature

成功應看到:

1
Good "git" signature

故障排除

  • ssh-keygen 顯示 security key not enabled:改用 WSL 的 OpenSSH 或更新到支援 FIDO 的版本。
  • Git 簽章顯示 unknown principal:確認 allowed_signers 開頭的 email 與 git config user.email 一致。
  • agent 簽章失敗:重新插拔 YubiKey、清除後重加金鑰(ssh-add -Dssh-add ...)。

參考資料