简介
SSH agent 是 OpenSSH 的核心部分。在这篇文章中,我将解释 SSH agent 是什么、如何使用它,以及它如何保护你的密钥。我还会介绍 agent 转发以及它的工作原理,并帮助你在使用 agent 转发时降低风险。此外,我还会分享在通过堡垒机访问内部主机时,你可以使用的替代方案。
什么是 SSH agent?
ssh-agent 是 SSH 的一个密钥管理器。它将你的密钥和证书以未加密的形式保存在内存中,随时可以供 ssh 使用。它让你不用在每次连接服务器时都输入密码短语。它在你的系统后台运行,独立于 ssh,通常在你重启后第一次运行 ssh 时启动。
SSH agent 通过不做以下操作来保证私钥的安全:
• 它不会将任何密钥材料写入磁盘。
• 它不允许导出你的私钥。
• 存储在 agent 中的私钥只能用于一个目的:签署消息。
但如果 agent 只能签署消息,SSH 如何加密和解密流量?
当第一次了解 SSH 的公钥和私钥时,很自然地认为 SSH 使用这些密钥对来加密和解密流量。我也曾这么认为,但事实并非如此。SSH 密钥对只在初始握手过程中用于身份验证。
例如,以下是用户密钥在 SSH 握手期间如何从服务器的角度验证的:
-
客户端向服务器提供一个公钥。
-
服务器生成并发送一个简短的随机消息,要求客户端使用私钥签署它。
-
客户端请求 SSH agent 签署消息,并将结果转发回服务器。
-
服务器使用客户端的公钥检查签名。
-
服务器现在证明了客户端持有其私钥。
在握手过程的后期,会生成一组新的临时对称密钥,用于加密 SSH 会话流量。这些密钥可能不会持续整个会话;定期会发生“重新密钥”事件。
agent 协议
SSH 使用 Unix 域套接字通过 SSH agent 协议与 agent 通信。大多数人使用 OpenSSH 附带的 ssh-agent,但也有各种开源替代品。
agent 协议非常简单,以至于你可以在一两天内编写一个基本的 SSH agent。它只有几个主要操作:
• 添加常规密钥对(公钥和解密后的私钥)
• 添加受限密钥对(公钥和解密后的私钥)
• 从智能卡添加密钥(仅限公钥)
• 移除密钥
• 列出存储在 agent 中的密钥
• 使用存储在 agent 中的密钥签署消息
• 使用密码锁定或解锁整个 agent
🤔 什么是受限密钥?受限密钥通常是有时效限制的密钥,或要求在使用时需要明确的用户确认的密钥。ssh-add 命令是 SSH agent 的接口。它执行除签名以外的所有操作。运行 ssh-add 不带任何参数时,它会扫描你的 home 目录寻找一些标准密钥,并将它们添加到你的 agent 中。默认情况下,它查找:
~/.ssh/id_rsa
~/.ssh/id_ed25519
~/.ssh/id_dsa
~/.ssh/id_ecdsa
一旦你将密钥添加到密钥链中,ssh 将自动使用它们。
ssh-agent 与 macOS Keychain
macOS 自带的 ssh-agent 可以将密钥的密码短语存储在 macOS 的 Keychain 中,这使得在重启后重新添加密钥变得更加容易。根据你的 Keychain 设置,在重启后你可能仍然需要解锁 Keychain。要将密钥密码短语存储在 Keychain 中,运行 ssh-add -K [密钥文件名]。密码短语通常存储在 “Local Items” Keychain 中。ssh-agent 将根据需要自动使用这些存储的密码短语。
什么是 agent forwarding?
SSH 的 agent 转发功能允许你的本地 SSH agent 通过现有的 SSH 连接透明地在更远的服务器上进行身份验证。例如,假设你 SSH 进入一个 EC2 实例,并且想要从那里克隆一个私有的 GitHub 仓库。如果没有 agent 转发,你需要在 EC2 主机上存储一份 GitHub 私钥的副本。有了 agent 转发,EC2 上的 SSH 客户端可以使用你本地计算机上的密钥来进行 GitHub 的身份验证。
agent forwarding 的工作原理
首先,来点背景知识。SSH 连接可以有多个通道。一个常见的例子是:与堡垒主机的交互式连接运行在一个通道上。当为连接启用 agent 转发(通常使用 ssh -A)时,会在后台打开第二个通道,将任何 agent 请求转发回你的本地机器。
从 ssh 的角度来看,远程和本地 ssh-agent 之间没有区别。SSH 始终查看 $SSH_AUTH_SOCK 环境变量来找到 agent 的 Unix 域套接字。当你使用启用了 agent 转发的连接连接到远程主机时,SSHD 会创建一个链接到 agent 转发通道的远程 Unix 域套接字,并导出一个指向它的 $SSH_AUTH_SOCK。
agent forwarding 带来的风险
当你将 ssh-agent 的 Unix 域套接字转发到远程主机时,它带来了一个安全风险:任何拥有远程主机 root 访问权限的人都可以通过该套接字偷偷访问你本地的 SSH agent。他们可以使用你的密钥在网络上的其他机器上冒充你。
如何降低 agent forwarding 的风险
这里有几种方法可以使 agent 转发更安全:
• 不要默认打开 ForwardAgent。
• 锁定你的 ssh agent,运行 ssh-add -x 用密码锁定 agent,运行 ssh-add -X 解锁它。
• 使用会在使用时提示的替代 SSH agent。
• 或者根本不使用 agent 转发。如果你要通过堡垒机访问内部主机,ProxyJump 是更安全的替代方案。
使用 ProxyJump:更安全的替代方案
当我们需要借助堡垒机来访问内网主机时,我们其实可以不用这么麻烦。因为现代的 SSH 还提供了一个更好的方法,那就是使用 ProxyJump 指令。ProxyJump 将你的本地 SSH 客户端的标准输入和输出通过堡垒机转发到远程主机。我们直接在本地操作就可以,不需要再登录堡垒机来做这个事了。
下一篇我们再详解怎么用 ProxyJump。
全文完!
如果你喜欢我的文章,欢迎关注我的微信公众号 deliverit。