3 min read

SSH 多路复用及长连接保持

SSH 多路复用及长连接保持

SSH 协议运行在TCP之上,当使用SSH与远程服务器建立连接时,你必须创建一条新的TCP连接。在你真正开始做有意义的动作之前,客户端和服务端都必须经过一系列协议交互,而这个协议交互的过程会花费一定的时间。

当远程部署使用SSH协议部署服务时,比如Ansible运行一个 playbook,它会创建许多SSH连接,用于传输文件或者运行命令等。Ansible每一次与服务器创建一条新SSH连接,都必须走一遍这样的协议交互。

OpenSSH是目前主流的SSH工具,如果你用的是 Linux或MacOS,那么几乎都会有预装的SSH客户端。OpenSSH支持一项优化,叫作SSH 多路复用(SSH multiplexing),有时候也叫作长连接保持(ControlPersist)。当你使用SSH多路复用连接同一个服务器的SSH会话时将会共享同一条TCP连接,这样消耗在TCP建立连接的时间就只会发生在第一次连接的时候。

当启用了多路复用:

  1. 首次SSH到服务器时,OpenSSH将启动主连接;
  2. OpenSSH创建一个UNIX 套接字(控制套接字,Control socket)维持与远程服务器的连接;
  3. 当下一次SSH到服务器时,OpenSSH将会使用已建立的控制套接字与服务器通信,而不再是重新建立新的TCP连接

主连接保持的时间根据用户的配置决定,超时后SSH客户端将会关闭这个连接。Ansible的默认配置是60s。

配置多路复用

SSH可以为给定计算机上的每个用户使用方便的配置文件。使用以下命令创建该文件:

# cat .ssh/config
Host *
    ControlMaster auto
    ControlPath ~/.ssh/%r@%h:%p.socket
    ControlPersist 10m

如果您连接到多个网络(例如您的LAN和/或WAN外部),则上述文件将起作用。该配置的细分为:

  • Host -连接名称
  • ControlMaster- 支持通过单个网络连接共享多个会话。设置为auto时,SSH将尝试使用主连接,但如果不存在,将回退到新连接。
  • ControlPath- 用于共享共享的控制unix套接字的路径。变量是:%r远程用户名,%h远程主机和%p远程端口。
  • ControlPersist- 保持时间,10m告诉SSH,如果超过10分钟都没有其它的SSH连接建立则关掉这个连接。

更倾向于Host 单服务器,而不是匹配所有

通过-O check 来检查是否建立了一个主连接:

ssh -O check user@Server

如果主进程正在运行的话,返回将会类似于:

Master running (pid=30656)

如果使用 ps 30656来查看对应的进程,结果则类似于:

PID TTY      STAT   TIME COMMAND
30656 ?        Ss     0:00 ssh: /root/.ssh/root@localhost:22.socket [mux]

也可以主动使用 -O exit 参数来主动强制关闭

ssh -O exit user@Server

正常连接时延测试

time ssh localhost /bin/true

real	0m0.023s
user	0m0.004s
sys	0m0.003s