Proxyjump原理和使用配置

内容简介
介绍SSH ProxyJump的原理和配置。

SSH ProxyJump 是 OpenSSH 原生支持的一种现代网络代理功能,专门用于通过中间服务器(通常称为“跳板机”或“堡垒机”)安全地连接到无法直接访问的目标服务器。

背景

在日常运维或开发工作中,我们常常需要访问部署在内网的服务器。然而出于安全策略或网络拓扑的限制,内网服务器并不会直接向外部暴露端口,导致我们无法直连。此时,跳板机(Jump Host/Bastion Host)就成了必不可少的中转:

  • 先通过 SSH 登录跳板机
  • 再从跳板机登录到目标服务器

虽然这样的流程能保证安全隔离,但也带来了一定程度上的不便:每次都要进行两次登录,甚至手动输入多次密码或在多个终端窗口间切换。如果有上传文件到目标服务器的需求,则需要先将文件上传到跳板机,再从跳板机传到目标服务器,操作非常繁琐。

ProxyJump 原理

当你使用 ProxyJump 时,你的本地客户端会首先与跳板机建立 SSH 连接。接着,客户端会在跳板机上启动一个临时的 SSH 子进程连接到目标主机。客户端将自身的输入输出通过加密隧道转发给这个子进程,从而在本地和目标服务器之间建立一条端到端的安全通道。关键点:整个过程中,跳板机仅负责透明地转发 TCP 流量,它不解密数据,也无法看到传输的具体内容。所有的身份认证(如密钥验证)都在你的本地机器和最终目标服务器之间直接完成。

兼容性与版本要求:

  • ProxyJump(-J)需要 OpenSSH 7.3+。
  • ProxyCommand 适用于更早版本的 SSH,兼容性更好,但配置稍微复杂一些。

这里更推荐使用 ProxyJump。在 ProxyJump 出现之前,通常需要使用传统的 ProxyCommand 结合 nc (netcat) 命令来实现类似功能,配置相对繁琐。ProxyJump 的优势在于:

  • 配置极简:语法更简洁,性能更好,无需在跳板机上启动额外的 nc 进程。
  • 兼容工具:不仅支持 SSH 登录,还能完美兼容 scp、sftp 等文件传输工具,甚至可以直接配合 VS Code 等现代开发工具使用。
  • 安全性高:中间跳板机不需要保存目标服务器的私钥,所有认证请求都由客户端发起。

常见误区和注意事项

  1. 跳板机通常位于受控网络的边缘,是唯一对外开放 SSH/端口访问的安全中转站。使用 ProxyJump 方案传输文件时,跳板机仅仅作为中转站,跳板机既看不到你传了什么文件,也无法篡改文件内容。数据流:本地电脑 ➡️ 跳板机 ➡️ 目标服务器。
  2. 因为跳板机仅仅作为数据流的中转站,所以跳板机不需要保存目标服务器的私钥或配置免密登录。所有的 SSH 认证请求,都是由你的本地电脑直接发起的。正确的密钥配置关系是:
    • 关系一(必须):本地电脑 ➡️ 跳板机(配置免密)
    • 关系二(必须):本地电脑 ➡️ 目标服务器(配置免密)
    • 关系三(不需要):跳板机 ➡️ 目标服务器(完全不需要配置任何免密或密钥)
  3. 虽然跳板机到目标服务器无需配置任何免密或密钥,但是数据流最终是路过跳板机后再到目标服务器上,所以跳板机和目标服务器要在同一内网,并且防火墙或者安全组对跳板机开放22端口访问。

配置方法

跳板机配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
vim /etc/ssh/sshd_config

# 1. 安全加固:禁用密码登录,强制使用密钥认证
PasswordAuthentication no
PubkeyAuthentication yes

# 2. 安全加固:禁止 root 用户直接远程登录
PermitRootLogin no

# 3. 核心功能:允许 TCP 端口转发(ProxyJump 依赖此功能)
AllowTcpForwarding yes

# 4. 安全加固:允许 SSH Agent 转发(可选,方便免密透传)
AllowAgentForwarding yes

# 5. 安全加固:禁用 X11 图形转发,减少攻击面
X11Forwarding no

# 配置完成后重启SSH服务使配置生效
systemctl restart sshd

客户端配置(本地电脑)

  1. 生成 SSH 密钥
    1
    
    ssh-keygen -t ed25519 -C "your_email@example.com"
  2. 部署跳板机 SSH 密钥
    1
    2
    
    # 配置免密连接跳板机
    ssh-copy-id -i ~/.ssh/id_ed25519.pub jump-user@jump-server-ip
    • jump-user:跳板机的用户名
    • jump-server-ip:跳板机的地址
  3. 编辑本地 SSH 配置文件
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    vim ~/.ssh/config
    
    # 1. 定义跳板机
    Host jump-server
        HostName 123.456.789.123       # 跳板机的公网 IP
        User jump-user                 # 跳板机登录用户名
        Port 22                        # 跳板机 SSH 端口
        IdentityFile ~/.ssh/id_ed25519 # 本地对应的私钥路径
        ServerAliveInterval 60         # 每60秒发送心跳,防止连接断开
        ServerAliveCountMax 3          # 3次无响应则断开
    
    # 2. 定义内网目标服务器
    Host target-server
        HostName 192.168.1.100         # 目标服务器的内网 IP
        User target-user               # 目标服务器登录用户名
        IdentityFile ~/.ssh/id_ed25519 # 目标服务器对应的私钥路径
        ProxyJump jump-server          # 指定通过上面定义的 'jump-server' 主机进行跳转
  4. 设置本地配置文件权限
    1
    
    chmod 600 ~/.ssh/config
  5. 部署目标服务器 SSH 密钥
    1
    2
    
    # 配置免密连接目标服务器
    ssh-copy-id -i ~/.ssh/id_ed25519.pub target-server

验证测试

  1. 验证ssh登录
    1
    
    ssh target-server
  2. 验证文件上传
    1
    
    scp -r my_folder target-server:/remote/path/
    • -r:代表递归(recursive)。这是传输文件夹的必加参数,它会让 scp 复制整个目录及其包含的所有子文件夹和文件。
    • /remote/path/:目标服务器上的绝对路径.
    • 路径末尾的斜杠:如果目标路径写为 /remote/path/(带斜杠),文件夹 my_folder 会作为子目录被放入该路径下(即 /remote/path/my_folder)。如果写为 /remote/path(不带斜杠),my_folder 里的所有内容会被直接平铺放入 /remote/path 中。建议始终带上斜杠以避免文件散落。
Buy me a coffee
beneliu 支付宝支付宝
beneliu 微信微信