在日常工作中,我们经常需要同时打开多个 SSH 连接到同一台服务器。每次连接都需要经历 TCP 握手、TLS 协商(如果是跳板机)、密钥交换等过程,既浪费时间又消耗资源。SSH 提供的 ControlMaster 特性可以让我们复用已建立的连接,大幅提升多会话场景下的效率。

什么是 ControlMaster?

ControlMaster 是 SSH 的连接复用功能。它允许在第一个 SSH 会话建立后,创建一个控制 socket(套接字文件)。后续的 SSH 连接可以通过这个 socket 复用已有的网络连接,无需重新建立 TCP 连接和身份验证。

核心优势:

  • 减少连接建立时间(从数秒缩短到毫秒级)
  • 降低跳板机/堡垒机负载
  • 支持多会话共享同一个加密通道

工作原理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
首次连接(无 ControlMaster):
  客户端 ----TCP 握手----> 服务器
  客户端 ----密钥交换----> 服务器
  客户端 ----认证-------> 服务器
  客户端 <---会话建立----

后续连接(无 ControlMaster):
  客户端 ----TCP 握手----> 服务器(重复一遍)
  ...

首次连接(启用 ControlMaster):
  客户端 ----TCP 握手----> 服务器
  客户端 ----密钥交换----> 服务器
  客户端 ----认证-------> 服务器
  客户端 <---会话建立----
  同时创建: /tmp/ssh-control/%r@%h:%p

后续连接(复用 ControlMaster):
  客户端 ----控制 socket通信----> 已有连接复用
  客户端 <---瞬间建立----

配置方法

方式一:全局配置文件

编辑 ~/.ssh/config

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 启用 ControlMaster
Host *
    # 自动复用连接(找不到 socket 时自动降级为普通连接)
    ControlMaster auto
    # 控制 socket 路径模板
    ControlPath ~/.ssh/sockets/%r@%h-%p
    # socket 目录权限(必须为 0700)
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlMaster auto
    ControlPersist 600

创建 socket 目录:

1
2
mkdir -p ~/.ssh/sockets
chmod 700 ~/.ssh/sockets

方式二:针对特定主机配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 为跳板机启用连接复用
Host bastion
    HostName bastion.example.com
    User admin
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p
    ControlPersist 4h

# 目标服务器(通过跳板机访问)
Host internal-server
    HostName 192.168.1.100
    User webadmin
    ProxyJump bastion
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p

方式三:命令行参数

1
2
3
4
5
# 首次连接,创建 master
ssh -o ControlMaster=yes -o ControlPath=/tmp/ssh-%r@%h:%p user@server

# 后续连接,自动复用
ssh -o ControlMaster=auto -o ControlPath=/tmp/ssh-%r@%h:%p user@server

关键参数详解

参数 说明
ControlMaster yes=强制启用, no=禁用, auto=自动(找不到 socket 则新建), ask=询问
ControlPath socket 文件路径模板,支持变量:%r(远程用户名)、%h(主机名)、%p(端口)、%l(本地主机名)
ControlPersist master 连接保持时间,单位秒;4h=4小时;yes=永久(慎用)

ControlPath 变量:

  • %r - 远程用户名
  • %h - 目标主机名(IP 或域名)
  • %p - SSH 端口(默认 22)
  • %l - 本地主机名
  • %C - 连接参数的哈希值(更复杂但更安全)

实际验证

查看当前活动的 socket

1
2
$ ls -la ~/.ssh/sockets/
srwx------ 1 admin admin 0 Jul  7 00:15 admin@bastion-22

验证连接复用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 第一个终端:建立连接
$ ssh -o ControlMaster=yes -o ControlPath=/tmp/test-%r@%h:%p user@server
# 保持连接...

# 第二个终端:查看 socket 已创建
$ ls -la /tmp/test-*
srwx------ 1 root root 0 Jul  7 00:15 root@server:22

# 第二个终端:连接时间大幅缩短
$ time ssh -o ControlMaster=auto -o ControlPath=/tmp/test-%r@%h:%p user@server echo "done"
done

real    0m0.021s  # 复用连接,毫秒级
vs
real    0m2.345s  # 全新连接

手动关闭 master 连接

1
2
3
4
5
6
# 方法1:等待 ControlPersist 超时
# 方法2:直接删除 socket 文件
rm ~/.ssh/sockets/admin@bastion-22

# 方法3:使用 ssh -O exit 退出 master
ssh -o ControlPath=~/.ssh/sockets/%r@%h-%p -O exit server

安全注意事项

1. ControlPath 权限

socket 文件权限必须严格控制:

1
2
3
4
5
# 确保目录权限为 700
chmod 700 ~/.ssh/sockets

# 确保 socket 只有所有者可读写
ControlPath ~/.ssh/sockets/%r@%h-%p

2. ControlPersist 的风险

1
2
3
4
5
6
7
# 风险:后台保持连接可能带来安全风险
ControlMaster yes
ControlPersist yes  # 永久保持,慎用

# 推荐:设置合理超时
ControlMaster auto
ControlPersist 600  # 10分钟后自动关闭

3. 多人共享服务器的注意事项

在多人共用的服务器上,建议:

  • 使用 %C(哈希值)替代简单变量,防止路径猜测
  • 或使用 ControlMaster=ask 确认每次复用
1
2
3
Host *
    ControlMaster ask
    ControlPath ~/.ssh/sockets/%C

4. Agent 转发

使用 ControlMaster 时,ssh-agent 转发行为有变化:

  • 所有复用同一 socket 的会话共享同一个 agent
  • 无法为每个会话指定不同的 agent

常见问题

Q: ControlMaster 不生效?

检查:

  1. socket 目录是否存在且权限正确
  2. ControlMaster 是否设置为 auto/yes
  3. ControlPath 是否正确
1
2
# 调试模式查看详情
ssh -vvv -o ControlMaster=auto -o ControlPath=~/.ssh/sockets/%r@%h-%p user@server

Q: socket 文件删除后报错?

1
2
3
# 自动降级为普通连接(ControlMaster=auto 时)
# 或手动重建:
ssh -o ControlMaster=yes -o ControlPath=~/.ssh/sockets/%r@%h-%p user@server

Q: ControlMaster 和 ProxyJump 同时使用?

完全兼容:

1
2
3
4
5
6
Host target
    HostName 10.0.0.5
    User app
    ProxyJump bastion
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h-%p

性能对比

场景 普通连接 ControlMaster
首次连接 ~2s ~2s
第二次连接 ~2s <0.1s
10次连接 ~20s ~2s
跳板机场景 每次验证 首次验证

总结

SSH ControlMaster 是提升 SSH 使用效率的利器,特别适合:

  • 频繁连接同一台服务器
  • 通过跳板机访问内网机器
  • 日常开发运维多会话场景

配置简单,效果显著。建议在 ~/.ssh/config 中全局启用,并使用 ControlMaster=auto 实现无感知复用。


参考来源: