使用YubiKey做SSH认证
完整步骤 1. 安装GPG2 2. 生成主密钥以及子密钥 3. 备份密钥以及撤销用证书 4. 发送公钥到公共服务器 5. 在私有服务器上安装GPG2 6. 在私有服务器上下载自己的公钥 7. 在私有服务器上导出自己的公钥为OpenSSH公钥 8. 配置客户端电脑(难点) 9. 转移子密钥到YubiKey
周一下单YubiKey 4,周二到货,当晚就开始折腾,总计搞了三天,也算是折腾明白了。
先说一下完整步骤
- 安装GPG2
- 生成主密钥以及子密钥
- 备份密钥以及撤销用证书
- 发送公钥到公共服务器
- 在私有服务器上安装GPG2
- 在私有服务器上下载自己的公钥
- 在私有服务器上导出自己的公钥为OpenSSH公钥
- 配置客户端电脑(难点)
- 转移子密钥到YubiKey
安装GPG2
打开 官方网站
Windoge 平台下载 Gpg4win,Mac 平台下载GnuPG for OS X。
然后自行安装,过程几乎就是一路下一步。
Mac 平台自行在 .profile
中添加 alias gpg='gpg2'
生成主密钥以及子密钥
生成主密钥
gpg --gen-key
接着输入一堆身份信息,这个密钥就生成了,然后输入 gpg -k
就能看到你当前的密钥,这里包含一个主密钥和一个子密钥。主密钥功能是 SC
也就是 sign
和 certificate
。一般而言,sign
功能是文件签名用,certificate
功能是证书签名用。子密钥功能是 E
,也就是 encrypt
,用于加密解密文件用。
通常主密钥被称作 private key
、secret key
、master key
,我们取master key
之意。
生成子密钥
生成签名子密钥
gpg --expert --edit-key 1A2B3C4D # 此处更换为你的主密钥 id
addkey
4 # RSA (sign only)
4096 # 密钥长度,2048 兼容好也足够安全,我是因为 YubiKey 4 支持4096
2y # 有效期分别为一直有效、天数、周数、月数、年数,按需选择
y # 是否正确
y # 再次确认是否创建
这样就创建了一个签名专用的子密钥(subkey)。
生成认证子密钥
gpg --expert --edit-key 1A2B3C4D # 此处更换为你的主密钥 id
addkey
8 # RSA (set your own capabilities)
S # 反选 Sign
E # 反选 EncryptE
A # 选择 Authenticate
Q # 完成功能选择
4096 # 密钥长度,2048 兼容好也足够安全,我是因为 YubiKey 4 支持4096
2y # 有效期分别为一直有效、天数、周数、月数、年数,按需选择
y # 是否正确
y # 再次确认是否创建
这样认证专用的子密钥也创建了。三个子密钥完成。
备份密钥以及撤销用证书
备份密钥
gpg --armor --output secret-key.txt --export-secret-keys
这会生成 secret-key.txt
文件,包含你的主密钥和所有子密钥,你也可以使用 export-secret-subkeys
指令来只导出单个/几个/所有子密钥,参数为至少一个密钥 id,以空格分开参数,如果 id 后跟感叹号,则表示单个导出,如果不跟则这个子密钥的所属的主密钥的下属所有子密钥都会导出(很拗口,就是所有同一主密钥的子密钥都会导出)。
备份撤销用证书
gpg --armor --output revoke.txt --gen-revoke 1A2B3C4D # 此处更换为你任一密钥 id
这会生成 revoke.txt
文件,包含撤销此主密钥的证书。
至此,密钥和撤销用证书的导出了,将它们存在一个安全的地方,譬如锁进柜子的u盘里面。
发送公钥到公共服务器
gpg --keyserver keyserver.ubuntu.com --send-key 1A2B3C4D # 此处更换为你的主密钥 id
目前测试 ubuntu
的密钥服务器国内可用。
在私有服务器上安装GPG2
我的服务器是 ubuntu
所以安装如下
sudo apt-get install gnupg2 -y
在私有服务器上下载自己的公钥
gpg2 --keyserver keyserver.ubuntu.com --recv-key 1A2B3C4D # 此处更换为你的主密钥 id
因为 gpg
是包含在大部分 linux
发行版中的,所以我们自己装的 gpg2
需要区别开来。
在私有服务器上导出自己的公钥为OpenSSH公钥
gpg2 --export-ssh-key 1A2B3C4D >> ~/.ssh/authorized_keys # 此处更换为你的主密钥 id
这个操作会将你认证用的子密钥转换成 OpenSSH
公钥,并添加到 ssh
公钥文件中。
配置客户端电脑
这算是整个流程中最耗费我时间的一点了,主要在于 Win7 上我的 gpg-agent 出错,原因从日志中找到了,但是没找到解决方案,最后在 Win10 上测试成功;再之后是因为 Mac 平台上我用的是 GnuPG for OS X
而不是常见的 GPGTools
。
Windoge 平台
前提条件
- Gpg4win
- putty
操作步骤
- 开始菜单打开 GPA
Edit
->Backend Preference
->GPG-Agent
- 勾选
enable-putty-support
,确定或者应用 - 命令行内输入
gpg-connect-agent reloadagent /bye
,这会重新载入gpg-agent
- 打开 putty,登陆之前配置的私有服务器,输入密钥的解密密码
Mac 平台
安装 pinentry-mac
brew install --cask pinentry-mac
配置 gpg-agent.conf
文件
文件路径:~/.gnupg/gpg-agent.conf
文件内容:
pinentry-program /usr/local/gnupg-2.1/bin/pinentry-mac.app/Contents/MacOS/pinentry-mac
enable-ssh-support
default-cache-ttl 600
max-cache-ttl 7200
配置 sshcontrol
配置要用的认证key
gpg2 -K --with-keygrip
echo 00112233445566778899AABBCCDDEEFF00112233 >> ~/.gnupg/sshcontrol
配置 .profile
先判断是否从客户端接入,如果不是则启用本地的agent
,否则会自动采用客户端的转发过来的agent
。
新增内容:
# GNUPG
if [ -z "$SSH_CLIENT" ] ; then
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent # 主要作用在于确保 gpg-agent 已经启动
fi
新开 shell 窗口,输入命令 gpg-connect-agent reloadagent /bye
重新载入 gpg-agent
(如果 gpg-connect-agent
不在环境变量中,那么你需要使用绝对路径,或者添加对应环境变量,或者建立软连接)。
导出ssh
公钥
gpg --export-ssh-key 11223344
然后把公钥输入到目标服务器的.ssh/authorized_keys
测试:
ssh you@your.server
弹出 pinentry
界面,输入密钥的解密密码
转移子密钥到YubiKey
- 设置你的 YubiKey 已经设置好 admin pin 和 pin
- 进入密钥编辑模式
gpg --edit-key 1A2B3C4D # 此处更换为你的主密钥 id
-
进入编辑模式后,依次选择 key 并使用 keytocard 转移 subkey 到智能卡对应的槽位
-
ssh 到你的私有服务器,弹出 pin 输入框即表示成功