如果存在套接字文件,SSH 可以复用该连接。为了创建套接字,我们使用:
ssh -M -S /tmp/hello [email protected]
例如,为了使用此套接字文件在服务器上运行命令:
ssh -S /tmp/hello example.com uname -a
SSH 在使用时需要host
字段-S /tmp/hello
,但并不关心。以下具有相同的效果:
ssh -S /tmp/hello whocares uname -a
为什么 SSH 需要但不关心主机名?
SSH 的这种行为(共享套接字文件 ( ) 描述的连接/tmp/hello
并忽略任何凭据)既是我想要的,也是我所期望的。但需要主机名有点令人困惑。
问题是这样的:如果我按如下方式使用此命令,是否会遇到问题:
ssh -S /path/to/my-first-host.socket example.com .... # expect connecting first host
ssh -S /path/to/my-second-host.socket example.com .... # expect connecting second host
ssh -S /path/to/my-third-host.socket example.com .... # expect connecting third host
答案1
~/.ssh/config
您可以通过、等根据 SSH 的主机名指定其他配置。/etc/ssh/ssh_config
虽然通过控制套接字连接时主机名本身可能并不重要,但在适用的情况下会应用这些选项:
$ cat ~/.ssh/config
Host foo
LocalForward 8080 localhost:9000
$ ssh -fMS /tmp/hello localhost sleep 1d
muru@localhost's password:
$ ssh -fS /tmp/hello foo sleep 1d & sudo lsof -i :8080
[1] 6971
[sudo] password for muru:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ssh 6859 muru 8u IPv6 148286 0t0 TCP ip6-localhost:http-alt (LISTEN)
ssh 6859 muru 9u IPv4 148287 0t0 TCP localhost:http-alt (LISTEN)
显然,SSH 应用了我在 中指定的端口转发规则~/.ssh/config
,即使它使用了控制套接字。事实上,端口转发是由创建套接字的进程完成的:
$ pgrep -fa hello
6859 ssh -fMS /tmp/hello localhost sleep 1d
6971 ssh -fS /tmp/hello foo sleep 1d
答案2
为什么 SSH 需要但不关心主机名?
因为控制套接字应该基于您要连接的主机名,如手册页中所述ssh_config
:
ControlPath
指定用于连接共享的控制套接字的路径,如上面的 ControlMaster 部分所述,或指定字符串 none 以禁用连接共享。 ControlPath 的参数可以使用波形符语法来引用用户的主目录或 TOKENS 部分中描述的令牌。 建议用于机会性连接共享的任何 ControlPath 至少包括 %h、%p 和 %r(或者 %C)并放置在其他用户不可写入的目录中。*这可确保共享连接被唯一标识。
如果您不遵循这些建议并尝试使用相同的套接字连接到不同的主机,ssh
请查找现有的套接字并使用它,无论写入的主机名如何。
对于编辑后的问题:
如果我按如下方式使用此命令,我会遇到问题吗?
ssh -S /path/to/my-first-host.socket example.com .... # expect connecting first host ssh -S /path/to/my-second-host.socket example.com .... # expect connecting second host ssh -S /path/to/my-third-host.socket example.com .... # expect connecting third host
是的。它现在没有强制/使用,但您显然正在使用未记录/未定义的行为,这些行为可能会在未来的某个版本中发生变化,恕不另行通知。
答案3
ssh -S
手册页中的部分请ssh
读者参阅(5) 手册页的ControlMaster
和部分。反过来它又指出,ControlPath
ssh_config
控制大师 允许通过单个网络连接共享多个会话。 [...]这些会话将尝试重用主实例的网络连接而不是启动新的网络连接,但如果控制套接字不存在或未侦听,则会恢复正常连接。
因此,总而言之,ssh
如果可以的话,请使用控制套接字,否则会退回到正常连接。为了实现正常连接,需要目标主机名。
顺便说一句,建议 aControlPath
的名称(模板)应至少包含目标主机名 ( %h
),以便不同的目标主机接收不同的控制路径值。如果您只是盲目地为每个连接使用任意不同的主机名值,则无法应用此建议。