Hshen
人若无名 便可潜心练剑
GitHub Abou byHshen Hshen

SSH Agent 详解与最佳实践

2019年8月17日

预计阅读:6min

SSH Agent 详解与最佳实践

SSH Agent 是一个密钥管理程序,可以帮助用户安全地管理私钥,并避免重复输入密钥密码。本文将详细介绍 SSH Agent 的工作原理及其在多跳主机场景中的应用。

SSH Agent 基本概念

SSH Agent 是一个在后台运行的程序,它可以:

  1. 存储解密后的私钥:您只需输入一次密码,私钥就会被加载到内存中
  2. 处理身份验证请求:当 SSH 客户端需要进行身份验证时,会向 SSH Agent 请求签名
  3. 提高安全性:私钥不需要传输到远程服务器,减少了风险
  4. 支持转发功能:可以实现无缝的多级跳转

基本使用方法

启动 SSH Agent

# 启动ssh-agent
eval $(ssh-agent -s)
# 输出类似:Agent pid 12345
 
# 查看当前ssh-agent进程
echo $SSH_AGENT_PID

添加密钥

# 添加默认密钥
ssh-add
 
# 添加指定密钥
ssh-add ~/.ssh/id_rsa_github
 
# 添加密钥并设置生命周期(秒)
ssh-add -t 3600 ~/.ssh/id_rsa
 
# 查看已添加的密钥
ssh-add -l
 
# 删除指定密钥
ssh-add -d ~/.ssh/id_rsa_github
 
# 删除所有密钥
ssh-add -D

SSH Agent 转发

SSH Agent 转发允许您在远程服务器上使用本地的 SSH 密钥,而无需将私钥复制到远程服务器。这在多跳主机环境中特别有用。

多跳主机场景

假设有三台服务器:

  • 本地主机(S1):您的工作站
  • 中间服务器(S2):跳板机/中转服务器
  • 目标服务器(S3):最终要访问的服务器

如果:

  • S1 的公钥已添加到 S2 和 S3 的授权文件中
  • 您可以从 S1 免密登录到 S2 和 S3
  • 但当您从 S1 登录到 S2,再从 S2 登录到 S3 时需要密码(因为 S2 没有您的私钥)

这种情况下,SSH Agent 转发可以解决问题。

启用 SSH Agent 转发

方案1:在 SSH 配置文件中设置

编辑 ~/.ssh/config 文件(如果不存在则创建):

# 全局启用转发
Host *
    ForwardAgent yes

# 或者只为特定主机启用转发
Host jumpserver
    HostName 192.168.1.100
    User username
    ForwardAgent yes

方案2:在命令行中使用 -A 参数

# 连接到远程服务器并启用SSH Agent转发
ssh -A username@hostname

方案3:在系统级配置文件中启用

编辑 /etc/ssh/ssh_config(全局配置)或 ~/.ssh/config(用户配置):

Host *
    ForwardAgent yes

验证 SSH Agent 转发

登录到中间服务器后,可以检查 SSH Agent 是否正常工作:

# 检查SSH_AUTH_SOCK环境变量
echo $SSH_AUTH_SOCK
 
# 尝试列出可用的密钥
ssh-add -l

实际工作流程

  1. 在本地机器(S1)上启动 SSH Agent:eval $(ssh-agent -s)
  2. 将您的私钥添加到 SSH Agent:ssh-add ~/.ssh/id_rsa
  3. 使用 SSH Agent 转发连接到中间服务器(S2):ssh -A username@S2
  4. 从中间服务器(S2)直接连接到目标服务器(S3):ssh username@S3
  5. 连接成功!S3 与 S1 的 SSH Agent 通信,实现了免密登录

安全注意事项

虽然 SSH Agent 转发非常方便,但也带来了一些安全风险:

  1. 只在信任的服务器上使用转发:恶意用户可能会利用转发的 SSH Agent 连接到其他您有权访问的服务器
  2. 限制转发范围:仅为需要的主机启用 ForwardAgent
  3. 使用密钥限制:使用 ssh-add -c 添加密钥,这样每次使用时都会请求确认
  4. 定期清理:不需要时,使用 ssh-add -D 清除所有已加载的密钥

高级用法

在 tmux 或 screen 会话中共享 SSH Agent

# 在~/.bashrc或~/.zshrc中添加
if [ -S "$SSH_AUTH_SOCK" ] && [ ! -h "$SSH_AUTH_SOCK" ]; then
    ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock

在 macOS 上配置 SSH Agent 持久化

macOS 默认使用 Keychain 管理 SSH 密钥。将以下内容添加到 ~/.ssh/config 文件:

Host *
    UseKeychain yes
    AddKeysToAgent yes
    IdentityFile ~/.ssh/id_rsa

使用 ssh-agent 转发与 ProxyJump 结合

# 在~/.ssh/config中配置
Host target
    HostName 192.168.1.200
    User username
    ProxyJump jumpserver
    ForwardAgent yes

通过正确配置和使用 SSH Agent,可以在保持安全性的同时,显著提高多服务器环境中的工作效率。