在日常开发和运维工作中,我们经常需要通过多台跳板机 SSH 到内网服务器。每次都需要在每台机器上配置密钥或者输入密码,非常麻烦。SSH Agent 转发(Agent Forwarding)正是解决这一问题的利器。

什么是 SSH Agent

SSH Agent 是一个后台运行的程序(守护进程),它负责管理用户的私钥。当你使用 SSH 连接服务器时,SSH Agent 会自动提供私钥进行认证,无需每次都输入密码或指定密钥文件。

核心组件

  • ssh-agent:后台守护进程,启动后会在环境变量中设置 SSH_AUTH_SOCK
  • ssh-add:用于将私钥添加到 agent 管理列表

工作原理

1
2
[本地主机] ----SSH 隧道----> [跳板机] ----SSH----> [目标服务器]
   (持有私钥)                     (转发请求)          (验证签名)

当启用 Agent Forwarding 后,跳板机会作为代理,将服务器的认证请求转发回本地主机,由本地的 SSH Agent 完成签名验证。

配置步骤

第一步:启动 SSH Agent

1
2
3
4
5
6
# 启动 ssh-agent
$ ssh-agent -s

# 输出示例:
# SSH_AUTH_SOCK=/tmp/ssh-XXXX/agent.259996; export SSH_AUTH_SOCK;
# SSH_AGENT_PID=260133; export SSH_AGENT_PID;

第二步:添加私钥

1
2
3
4
5
6
7
# 将私钥添加到 agent
$ ssh-add ~/.ssh/id_ed25519

# 查看已添加的密钥
$ ssh-add -l

# 256 SHA256:oNMkb9zE/4R3Gb5PRtSqdWyfXQ93QPzFSfPd8M9XbbA test@secdoc (ED25519)

第三步:配置 SSH 客户端

~/.ssh/config 中启用 Agent Forwarding:

1
2
3
4
5
6
7
8
9
# 为特定主机启用 Agent Forwarding
Host bastion-server
    HostName 192.168.1.100
    User admin
    ForwardAgent yes

# 或者使用通配符匹配所有跳板机
Host bastion-*
    ForwardAgent yes

第四步:连接测试

1
2
3
4
5
6
# 直接 SSH 到目标服务器(通过跳板机的 ProxyJump 场景)
ssh -J bastion-server target-server

# 或者在跳板机上直接 SSH 到内网服务器
ssh -A admin@bastion-server
ssh -A admin@target-server   # 跳板机上执行,使用转发的 agent

验证 Agent 转发是否生效

在跳板机上执行:

1
2
3
4
5
6
7
# 检查环境变量(如果能看到 SSH_AUTH_SOCK,说明转发成功)
$ echo $SSH_AUTH_SOCK
/tmp/ssh-XXXX/agent.259996

# 尝试列出本地 agent 中的密钥
$ ssh-add -l
256 SHA256:oNMkb9zE/4R3Gb5PRtSqdWyfXQ93QPzFSfPd8M9XbbA test@secdoc (ED25519)

安全风险

虽然 Agent Forwarding 非常方便,但存在显著的安全风险,需要谨慎使用。

主要风险

  1. 跳板机拥有者可以冒用身份

    跳板机管理员可以连接到相同的 socket,冒用你的身份访问其他服务器。Agent 只验证请求来自同一个 socket,而非特定进程。

  2. 私钥暴露风险

    如果跳板机被攻破,攻击者可以尝试对你的私钥进行离线暴力破解。

  3. Agent 权限提升

    跳板机上的任何用户只要知道 socket 路径,就可以使用你的身份。

安全最佳实践

1. 限制 Agent 转发范围

只对可信的跳板机启用 Agent Forwarding:

1
2
3
4
5
6
7
8
Host known-bastion
    HostName 192.168.1.100
    User admin
    ForwardAgent yes

# 其他主机默认禁止转发
Host *
    ForwardAgent no

2. 添加密钥密码保护

始终使用密码保护私钥:

1
2
3
4
5
# 生成带密码的密钥
$ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519

# 添加到 agent 时只需输入一次密码
$ ssh-add ~/.ssh/id_ed25519

3. 使用 ECDSA/SK 或 Ed25519-SK 硬件密钥

这类密钥存储在硬件设备(如 YubiKey)上,私钥永远不会被导出到内存:

1
2
# 生成硬件密钥(需要 YubiKey)
$ ssh-keygen -t ed25519-sk -O resident -O verify-required

4. 定期检查 Agent 状态

1
2
3
4
5
# 查看当前 agent 中的密钥
$ ssh-add -l

# 查看密钥指纹详情
$ ssh-add -l -v

5. 使用 SSH 证书代替密钥

通过 SSH 证书可以限制有效期和授权范围,即使证书泄露,风险也更可控:

1
2
# CA 签发用户证书
$ ssh-keygen -s ~/.ssh/ca -I "user@host" -n user -V +1d ~/.ssh/id_ed25519.pub

常见问题

Q: Agent Forwarding 不生效?

检查以下几点:

  1. 确认本地已启动 ssh-agent 并添加了密钥
  2. 确认 SSH 配置中 ForwardAgent yes 已设置
  3. 确认跳板机的 sshd_configAllowAgentForwarding yes(默认开启)
  4. 使用 ssh -v 查看详细日志排查

Q: 跳板机上看到 SSH_AUTH_SOCK 为空?

这是正常的——SSH Agent Forwarding 不需要跳板机设置环境变量。请求会通过 SSH 协议转发,不需要在跳板机上运行 ssh-agent。

Q: 如何同时管理多个身份?

使用 ~/.ssh/config 配置多个身份:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 工作账户
Host work-server
    HostName 10.0.0.10
    IdentityFile ~/.ssh/work_id_ed25519
    ForwardAgent yes

# 个人账户
Host personal-server
    HostName 10.0.0.20
    IdentityFile ~/.ssh/personal_id_ed25519
    ForwardAgent yes

总结

SSH Agent 转发是管理多跳 SSH 访问的强大工具,能显著提升工作效率。但使用时必须权衡便利性与安全性:

  • ✅ 仅对可信跳板机启用
  • ✅ 使用带密码保护的密钥
  • ✅ 考虑使用硬件安全密钥
  • ✅ 定期审计和清理不再使用的密钥

对于高敏感场景,建议使用 SSH 证书或专用的临时密钥,限制有效期和访问范围。


参考来源