菜鸟科技网

ssh 代理命令

  1. ssh -A (SSH Agent Forwarding):这是最常用、最核心的“SSH 代理”功能,它允许你将本地的 SSH 私钥安全地“传递”到远程服务器上,用于继续跳转到其他服务器。
  2. ProxyCommand:这是一个更底层的配置,允许你指定一个命令(通常是另一个 SSH 连接)来建立与最终目标主机的连接,常用于创建复杂的网络路径。

我会重点讲解第一种,因为它解决了绝大多数代理场景的需求,然后简要介绍第二种。

ssh 代理命令-图1
(图片来源网络,侵删)

核心概念:SSH Agent Forwarding (ssh -A)

它是什么?

想象一下这个场景:

  • 你的电脑(本地机器, Laptop)在 A 网络。
  • 有一台跳板机(堡垒机, Bastion Host),它在 B 网络,你只能通过 SSH 密钥登录它。
  • 在跳板机后面,有一台数据库服务器(目标服务器, Target Server),它只能在堡垒机所在的网络中访问,并且也只接受来自堡垒机的 SSH 密钥登录。

没有 Agent Forwarding 时的麻烦做法:

  1. 你需要将你的私钥(id_rsa)复制一份到堡垒机上。
  2. 设置好权限 chmod 600 ~/.ssh/id_rsa_on_bastion
  3. 每次从堡垒机登录到目标服务器时,都需要输入密码(如果私钥有密码)或者手动指定密钥文件。

这种做法很糟糕,因为它:

  • 不安全:你的私钥副本会留在堡垒机上,增加了泄露风险。
  • 不方便:需要手动同步密钥,如果私钥更新了,还得再复制一遍。
  • 不灵活:如果你有多个开发者,每个都需要在堡垒机上配置自己的密钥。

使用 SSH Agent Forwarding (ssh -A) 的优雅做法: 你只需要一条命令:

ssh 代理命令-图2
(图片来源网络,侵删)
# -A 参数开启了 Agent Forwarding
ssh -A user@bastion-host

登录到堡垒机后,你发现可以直接无密码登录到目标服务器:

# 在 bastion-host 上执行
ssh user@target-server

神奇之处在于: ssh -A 告诉堡垒机:“嘿,当我需要验证身份时,不要用你本地的私钥,而是帮我向我的本机(Laptop)的 SSH Agent 请求一个临时的、一次性的签名。” 整个过程是加密和安全的,你的私钥从未离开过你的本地机器。

它是如何工作的?

  1. 本地启动 SSH Agent:你的本地机器上必须有一个正在运行的 ssh-agent,它会缓存你的私钥,并响应签名请求。

    • 检查是否运行:echo $SSH_AUTH_SOCK (如果输出一个路径,说明正在运行)。
    • 启动它:eval "$(ssh-agent -s)"
    • 添加私钥到 Agent:ssh-add ~/.ssh/id_rsa (它会提示你输入密码,之后一段时间内就无需再输)。
  2. 建立连接:当你执行 ssh -A user@bastion 时:

    ssh 代理命令-图3
    (图片来源网络,侵删)
    • 你的本地 ssh 客户端连接到堡垒机。
    • 它在连接中包含了一个特殊的“认证代理协议”信息,告诉堡垒机:“我有一个可用的认证代理,地址是 ”。
  3. 远程服务器上的行为:当你从堡垒机再执行 ssh user@target 时:

    • 目标服务器会向堡垒机请求你的公钥进行验证。
    • 堡垒机不会用自己的私钥,而是它会反向连接回你的本地机器的 ssh-agent(通过之前建立的加密通道)。
    • 本地 ssh-agent 收到请求,用你的私钥对一段随机数据进行签名,然后将签名发回给堡垒机。
    • 堡垒机将这个签名转发给目标服务器。
    • 目标服务器用你的公钥验证这个签名,如果成功,就允许你登录。

如何使用?

命令行方式(临时生效):

# 登录到远程服务器,并开启 Agent Forwarding
ssh -A user@remote-host
# 如果已经登录了,可以重新打开一个会话来开启
ssh -A user@remote-host

配置文件方式(永久生效,推荐): 编辑你的 ~/.ssh/config 文件,为需要代理的主机添加 ForwardAgent yes

# ~/.ssh/config
# 为堡垒机配置 Agent Forwarding
Host bastion
    HostName 192.168.1.100
    User myuser
    ForwardAgent yes
# 为目标服务器配置,并指定通过堡垒机跳转
Host target
    HostName 10.0.0.50
    User myuser
    # 这一步是可选的,但能简化命令
    ProxyCommand ssh -W %h:%p bastion 
    # ProxyCommand 没用,也可以手动登录 bastion 后再登录 target
    # ForwardAgent yes # 如果堡垒机是中间跳板,这个配置通常加在 bastion 的 Host 条目里就够了
# 另一个例子:所有 github.com 的连接都通过代理
Host github.com
    HostName github.com
    User git
    # 假设你的代理服务器地址是 proxy.example.com
    ProxyCommand nc -X 5 -x proxy.example.com:1080 %h %p

配置好后,你就可以直接登录了:

ssh target  # 会自动通过 bastion 跳转,Agent Forwarding 也生效了

进阶概念:ProxyCommand

ProxyCommand 是一个更底层的工具,它不关心认证,只关心如何建立网络连接,它告诉 ssh 客户端:“不要直接连接目标主机,而是先执行我给你的这个命令,然后将该命令的标准输入和输出作为与目标主机通信的通道”。

它是什么?

ProxyCommand 允许你将 ssh 的输入和输出“管道”给另一个命令,这个命令通常是另一个 ssh 进程,用于建立跳板,但它也可以是 nc (netcat) 或其他任何可以建立网络连接的程序。

如何使用?

最经典的用法是通过一个中间服务器跳转。

示例:通过跳板机连接目标服务器

假设你有:

  • 跳板机:bastion.example.com
  • 目标服务器:db.internal.com (无法从外网直接访问)

使用 ssh -W (现代、简洁)

这是目前推荐的方式,ssh -W 会自动处理数据转发。

在你的 ~/.ssh/config 中:

Host bastion
    HostName bastion.example.com
    User myuser
Host db
    HostName db.internal.com
    User myuser
    # 告诉 ssh: 先通过 bastion 建立一个隧道,然后将所有通信转发到 db 的 22 端口
    ProxyCommand ssh -W %h:%p bastion 

你只需要执行 ssh dbssh 会自动在后台执行 ssh -W db.internal.com:22 bastion,为你建立好连接。

使用 nc (Netcat)

如果跳板机上没有 nc 或者你想用更通用的方式,可以这样配置:

Host db
    HostName db.internal.com
    User myuser
    # 在 bastion 上执行 nc,连接到 db 的 22 端口
    # %h 会被替换成 db.internal.com, %p 会被替换成 22
    ProxyCommand ssh bastion nc %h %p

这种方式要求你的跳板机上安装了 nc 并且能正常工作。

命令行方式(临时生效):

# 手动输入密码,比较繁琐
ssh -o "ProxyCommand ssh user@bastion nc %h %p" user@db.internal.com
# 结合 Agent Forwarding,更强大
ssh -A -o "ProxyCommand ssh -A user@bastion nc %h %p" user@db.internal.com

总结与对比

特性 ssh -A (Agent Forwarding) ProxyCommand
目的 身份验证代理:将本地私钥安全地用于远程服务器。 连接代理:通过一个中间主机建立到目标主机的网络通道。
解决的问题 避免将私钥复制到跳板机上,简化多级服务器的登录流程。 解决网络隔离问题,通过一个可访问的中间主机连接到内网或防火墙后的主机。
工作层面 认证层面工作。 网络连接层面工作。
典型用法 ssh -A user@bastion
Host ... ForwardAgent yes
Host ... ProxyCommand ssh -W %h:%p bastion
Host ... ProxyCommand ssh bastion nc %h %p
依赖 需要本地 ssh-agent 正在运行并加载了私钥。 不依赖 ssh-agent,但需要中间主机能执行连接命令(如 nc 或另一个 ssh)。

最佳实践:

  1. 首先配置 ~/.ssh/config,把所有主机、用户、端口、代理规则都写好,这是最方便、最不容易出错的方式。

  2. 对于需要跳板机的场景,ForwardAgent yesProxyCommand 结合使用,可以实现一次登录,畅通无阻。

    # ~/.ssh/config
    Host bastion
        HostName 1.2.3.4
        User ec2-user
        ForwardAgent yes
    Host app-server
        HostName 10.0.1.55
        User app-user
        ProxyCommand ssh -W %h:%p bastion 

    你只需要在本地运行 ssh app-server,就能无密码、无感地通过堡垒机登录到应用服务器,并且所有后续的 scpgit 等操作都能自动使用你的本地私钥。

分享:
扫描分享到社交APP
上一篇
下一篇