Contents

Yubikey with SSH

最近入手了一个 Yubikey,其中用来做 SSH 登录。一路操作下来,踩不少坑,等到终于使用 Yubikey 中的 Authentication key 登录上机器后发现:

我好像没法拿着这个 Yubikey 随便找台机器登录呀(并不包括 Windows)。

Yubikey 自带 key 的这个优势(杂耍)体现不出来呀,总不能到处登录笔记软件吧。

所以为了满足能随便找台机器都能登录这一需求(伪),特此写(水)一篇文章,介绍一下如何使用 Yubikey SSH 登录机器。

准备工作

  • 配置好 OpenPGP 功能的 Yubikey

没有配置好的同学可以参照这篇文章:YubiKey4 我踩过的那些坑 写得相当详细了。(广告费后台结一下)

  • 随便找到的使用 *nix 操作系统的机器
  • 安装好 GnuPG 套件

布置马戏团

把这段脚本放到 shell profile 中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# GPG ssh support
export GPG_TTY=$(tty)
gpg-connect-agent updatestartuptty /bye
unset SSH_AGENT_PID
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)

function gpg_ssh_clear() {
    keys=$(gpg-connect-agent 'keyinfo --ssh-list --ssh-fpr' /bye | grep KEYINFO | awk '{print $3}' | head)
    for key in $keys; do gpg-connect-agent "delete_key $key --force" /bye; done
}

gpg-agent 有模拟 OpenSSH agent 的功能,所以可以用 gpg-agent 替代 ssh-agent,设置 SSH_AUTH_SOCKSSH_AGENT_PID 以达成目的。

使用 gpg-agent cache SSH key 后,ssh-add -D 将不再起作用,如果需要删除 gpg-agent cache 的 key,得使用 gpg-connect-agent。所以我写了个函数,拿出所有的 gpg-agent cache 的 SSH key,并删除。想清理时,执行 gpg_ssh_clear 即可。(并不会清除 Yubikey 里面的 key)

添加内容到 ~/.gnupg/gpg-agent.conf 文件中:

1
2
3
4
5
enable-ssh-support
write-env-file
use-standard-socket
default-cache-ttl 600
max-cache-ttl 7200

pinentry-program 这边给出的是 macOS 的示例,其他的 OS 可以参考这个回答

拿到表演钥匙

输入 gpgconf --reload gpg-agent 重载配置,插上 Yubikey,GnuPG 会自动检测到并把 key 加入到 agent 里面。

接着 ssh-add -L 就能看到一个备注为 cardno:card-idopenpgp:key-id 的 SSH pubilc key 了。

杂耍

找台机器(或者可以 ssh 自己),公钥一丢,直接 ssh 走起,输入 Yubikey PIN 后,直接就登录上去了。

完全不需要把 private key 复制到机器上冒着泄漏的风险,想在哪登,就在哪登。(所以我为啥不出门自带机器。。。(这不重要!))

抛 12 个球!

如果希望让整个 SSH 授权过程更为庄重(增加节目效果),你可以在授权前要求触碰 Yubikey 才能完成授权。

通过安装官方的 ykman 设置:

1
ykman openpgp set-touch aut on

这样每次 ssh 用到 Yubikey 的 key 授权时,Yubikey 的指示灯都会一闪一闪表示需要触碰才能完成操作。

When the yubikey is pressed, then you have my permission to die (authenticate) – Bane (

还有一件事

目前这个方案用户体验上有个不舒服的地方,每次 ssh-add 添加普通的 SSH key 的时候,GPG 都会跳出来要求一个密码用来保护加入的 SSH secret key。好在添加 SSH key 不算是高频操作,所以也还能接受。

GPG snippets

放上一些 GPG snippet,方便查阅。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Reload
gpgconf --reload gpg-agent

# Kill
gpgconf --kill gpg-agent

# List options
gpgconf --list-options gpg-agent

# This is an undocumented command to export ssh public key
pgp --export-ssh-key <Key ID>

# Quickly start gpg-agent
gpg-connect-agent /bye

参考