加速 SSH:为更快会话实施连接多路复用
使用 SSH 连接到远程主机是系统管理员和开发人员的一项基本任务。然而,初始连接过程——包括密钥交换、加密协商和完整身份验证——可能会引入明显的延迟,尤其是在频繁连接或自动化需要多次快速会话的任务时。
SSH 连接多路复用是一种强大但通常未被充分利用的技术,旨在解决此延迟问题。通过为多个后续会话(从属会话)重用一个底层网络连接(主会话),可以消除加密握手的开销,从而在初始设置后实现近乎即时的连接。本指南将引导您了解如何使用 ControlMaster 和 ControlPersist 指令设置和优化 SSH 连接多路复用。
理解 SSH 连接开销
默认情况下,每个标准的 SSH 会话都会建立一个全新的 TCP 连接并执行完整的握手。此过程包括:
- 密钥交换: 确定共享密钥和加密算法。
- 身份验证: 验证用户凭据(密码、密钥文件或双因素令牌)。
- 会话设置: 初始化终端或命令通道。
虽然这确保了最大的安全性,但它通常会为每次会话增加 0.5 到 2 秒的启动时间,尤其是在高延迟链路上。连接多路复用通过保持身份验证机制处于活动状态并将新会话路由到已建立的安全通道来避免这种重复的成本。
多路复用如何工作
连接多路复用利用本地 Unix 域套接字(本地机器上的一个文件)在主 SSH 进程和任何新的从属进程之间进行通信。
- 主连接: 您运行的第一个 SSH 命令会创建持久连接并设置通信套接字。
- 控制路径: 后续会话用于检查和连接到主机的指定本地文件路径(套接字)。
- 从属连接: 任何后续针对同一主机的 SSH 命令都通过本地套接字连接到主控,完全绕过网络握手。
关键配置指令
要启用连接多路复用,您需要在 SSH 客户端设置中进行配置,通常在特定于用户的配置文件(~/.ssh/config)中。三个关键指令是 ControlMaster、ControlPath 和 ControlPersist。
1. ControlMaster
此指令指定 SSH 是否应尝试创建主连接或重用现有连接。
| 值 | 描述 |
|---|---|
no |
(默认) 标准的单次连接模式。 |
yes |
强制会话成为主控并等待从属连接。(如今很少单独使用)。 |
auto |
首选设置。如果存在主连接,则重用它;否则,启动一个新的主连接。 |
对于大多数现代配置,设置 ControlMaster auto 是最佳实践。
2. ControlPath
用于通信的 Unix 域套接字文件的路径。此路径对于每个远程主机、用户和端口组合必须是唯一的,以防止会话混淆控制通道。
在路径中使用变量可确保唯一性:
| 变量 | 描述 |
|---|---|
%r |
远程用户名 |
%h |
远程主机名 |
%p |
远程端口 |
示例 ControlPath:
ControlPath ~/.ssh/sockets/%r@%h:%p
提示: 始终为这些套接字创建专用的目录(
mkdir -p ~/.ssh/sockets)并确保它具有安全的权限(chmod 700 ~/.ssh/sockets)。
3. ControlPersist
这是对性能影响最大的指令,因为它告诉主连接在初始命令完成后保持打开状态的时间。
在 ControlPersist(OpenSSH 5.6 中引入)之前,主连接必须保持附加到终端会话。有了 ControlPersist,主进程就会分离并在后台保持活动状态。
| 值 | 描述 |
|---|---|
no |
终端关闭时,主连接立即关闭。 |
yes |
主连接无限期持续存在(直到手动关闭或系统重启)。 |
| 时间值 | 指定持续时间(例如,5m 表示 5 分钟,1h 表示 1 小时)。连接在该不活动期后关闭。 |
设置 ControlPersist 10m 通常足以满足典型的会话需求。
实际在 ~/.ssh/config 中的实现
下面是在 SSH 客户端配置文件中配置多路复用的示例。
示例 1:全局配置
此配置将连接多路复用应用于您连接的所有远程主机,假设它们运行在标准端口 22 上。
# 所有主机的配置 (*)
Host *
# 启用连接重用或启动
ControlMaster auto
# 在最后一个会话关闭后保持连接活动 15 分钟
ControlPersist 15m
# 定义套接字路径,确保基于用户、主机和端口的唯一性
ControlPath ~/.ssh/sockets/%r@%h:%p
# 可选:在低带宽链路上启用压缩以进一步加速
Compression yes
示例 2:特定于主机的配置
将多路复用限制在频繁访问的主机或组中通常是更好的做法。
# 匹配 'prod-*' 的主机的配置
Host prod-*
HostName %h.example.com
ControlMaster auto
ControlPersist 5m
ControlPath ~/.ssh/sockets/%r@%h:%p
# 特定于跳板主机(可能需要更长的持久性)的配置
Host jumpbox
ControlMaster auto
ControlPersist 1h
ControlPath ~/.ssh/sockets/%r@%h:%p
用法、验证和管理
1. 验证速度提升
您可以使用 time 命令轻松验证性能提升。
多路复用之前(首次连接):
$ time ssh myhost exit
real 0m1.234s
user 0m0.045s
sys 0m0.015s
多路复用之后(后续连接):
$ time ssh myhost exit
real 0m0.045s # 实际时间急剧减少
user 0m0.005s
sys 0m0.003s
2. 检查主连接状态
建立主连接后,套接字文件将存在于您指定的 ControlPath 中。您可以使用 -O(控制选项)标志检查连接状态。
# 检查到 myhost 的连接是否活动
ssh -O check myhost
如果成功,输出将确认套接字连接已打开。
3. 终止主连接
如果您需要立即关闭持久主连接(可能是因为身份验证凭据已更改或需要测试新配置),请使用 exit 控制选项:
# 终止到 myhost 的主连接
ssh -O exit myhost
此命令指示主进程正常关闭。后续会话随后将被强制创建新的主连接。
故障排除和最佳实践
目录和权限
安全至关重要。SSH 创建的套接字文件包含有关您连接的元数据,包括潜在的控制命令。确保套接字目录的权限受到限制。
# 如果不存在,则创建目录
mkdir -p ~/.ssh/sockets
# 设置严格权限(仅所有者可访问)
chmod 700 ~/.ssh/sockets
控制多个用户
如果您使用不同的用户名连接到同一主机,多路复用会自动处理这种情况,因为 ControlPath 中的 %r(远程用户)变量确保为 user1@host 和 user2@host 创建单独的套接字。
与其他客户端的冲突
如果您运行依赖于 SSH 的自动化脚本或工具,请确保它们配置为使用相同多路复用设置,或在必要时明确禁用它。如果脚本需要确保新的连接,您可以在命令行上强制执行非多路复用的行为:
ssh -o ControlMaster=no user@host
总结
SSH 连接多路复用是一种非常有效的性能优化技术。通过配置 ControlMaster auto、指定唯一的 ControlPath 并使用 ControlPersist,您可以消除与频繁使用 SSH 相关的重复加密开销。这使得会话启动时间明显加快,无论您是交互式工作还是运行自动化脚本,都能提高工作效率。