7个版本
0.1.5 | 2023年11月12日 |
---|---|
0.1.4 | 2022年5月27日 |
0.1.3 | 2021年12月26日 |
0.1.2 | 2020年3月23日 |
0.0.0 | 2019年2月13日 |
#199 在 加密学 中
38KB
586 行
ssh-gpg-agent
ssh-gpg-agent 是一个替代SSH代理实现,它透明地支持PGP加密的私有SSH密钥,而不是依赖于密码保护。与GnuPG或OpenSSH提供的SSH代理不同,不需要将它们“添加”到代理中——在给定目录中,密钥发现是自动的。
背景
对于给定的用户,对于要连接的所有主机拥有单个SSH密钥而不是共享密钥可能是有益的。好处包括但不限于
- 密钥泄露只会影响单个服务
- 简化跟踪特定密钥的使用情况:文件名可以识别它所使用的服务,而公钥的注释(如服务
authorized_keys
文件中可见)作为指向私钥持有者的反向链接 - 当使用单个密钥为所有服务时,不存在可合理否认的可能性——相同的密钥意味着相同的使用者
同时,建议不要在任何系统上以未加密的形式存储私钥。密码保护就派上用场了。
虽然密码提供安全感和轻松感,但有时也不方便:每次建立SSH连接时都需要重复输入密码。
这就是SSH代理发挥作用的地方,在请求密钥密码一次之后,将敏感密钥材料缓存一段时间或直到系统重启,具体取决于用户的偏好。
问题
然而,当需要连接到许多系统时,每个系统都使用不同的密钥对进行身份验证,即使是系统运行期间只输入一次密码,对用户来说仍然是一项重大的负担。
解决方案
为了绕过加密密钥重复输入密码,为何不利用许多系统上已经可用的加密程序:GnuPG。
ssh-gpg-agent作为SSH代理,假定使用PGP加密的私有SSH密钥文件,并且可以通过GnuPG透明地解密这些密钥。如果使用代理来处理GnuPG密钥,SSH密钥的解密可以降级为不需要任何用户交互的后台活动。
此外,如果使用智能卡进行解密,还有一个额外的好处,即只需将其从系统中移除,就可以防止SSH密钥的自动化使用。
设置
要使用代理的第一步是,应使用GnuPG重新加密现有的密码保护SSH密钥。
以下函数可以简化此任务
function encrypt() {
if [ $# -le 1 ]; then
echo "Usage: encrypt <ssh-key-file> <gpg-identity-to-encrypt-to>"
return
fi
mkfifo -m 0600 _fifo && \
(cat "${1}" > _fifo && \
cat "${1}" > _fifo && \
gpg --encrypt --recipient="${2}" --yes --output="${1}".gpg < _fifo &) && \
ssh-keygen -p -N "" -f _fifo && \
rm _fifo
}
此函数应用于单个密钥时,将要求输入密钥的当前密码,将其解密,并加密到指定的GnuPG身份或接收者。
例如
encrypt '~/.ssh/d-e-s-o@github:access_2018-01-01' 'deso@posteo.net'
结果是带有扩展名.gpg
的新文件,其中包含加密的密钥。原始文件保持不变。它可以保留作为后备(例如,在智能卡使用的情况下,卡不可用)。
安装代理(例如通过cargo install ssh-gpg-agent
)后,可以直接启动。默认情况下,它将在用户的~/.ssh/
目录中工作,并用于服务具有关联.gpg
文件的标识。
代理监听请求的Unix域套接字位于系统的tmp目录中,名称为ssh-gpg-agent.sock
。
SSH_AUTH_SOCK
环境变量应指向此路径,以指示ssh
使用ssh-gpg-agent
(如果希望系统范围内使用)。
或者,如果代理仅用于一组主机,可以在~/.ssh/config
中配置代理以用于相关的主机。
Host github
Hostname github.com
User git
IdentityFile ~/.ssh/d-e-s-o@github:access_2018-01-01
# Use ssh-gpg-agent for this host:
IdentityAgent /tmp/ssh-gpg-agent.sock
设置完成后,可以使用PGP加密的SSH密钥透明地解密,并用于与指定主机的身份验证。
更多优势
ssh-gpg-agent的使用相对于典型工作流程提供了一些额外的优势
- 不再需要将密钥添加到代理中,这只是一个不透明的二级密钥管理机制,通常是一个混淆的来源,或者其参与简单地被遗忘
- 代理是无状态的:公钥按需加载;私钥永远不会缓存,而是每次身份验证请求时进行解密(注意,所使用的
gpg-agent
将是状态化的,但此代理不会引入额外的状态来管理) - 当与存储GnuPG身份密钥的智能卡一起使用时,物理移除卡就足以防止通过代理管理的SSH密钥的进一步使用
- 它有效地提供了一种方法,在配合智能卡(物理卡和PIN码以及密钥本身)使用SSH密钥时,实现多因素身份验证,这比单纯的密码更安全
- 现有的密码保护密钥材料可以保持原样,并用作后备/备份
替代方法
ssh-gpg-agent只是解决使用每个主机的SSH密钥时重复输入密码问题的解决方案之一。其他解决方案包括
- 使用
PRESET_PASSPHRASE
gpg-agent
命令预设置密码短语(这又为系统增加了另一个间接层) - GnuPG从概念上支持
protected-shared-secret
密钥格式,这可能在某些情况下可用于在密钥之间共享密码,也许有方法将其连接到SSH密钥,但此格式在当前的GnuPG版本中尚未实现(即,包括版本2.2及更高版本)
依赖关系
~9-21MB
~347K (估计值) SLoC(约额外代码行数)