0xC*_*22L 7 openssh ssh-tunneling port-forwarding
注意:我使用的 OpenSSH 客户端都是7.2 版,所以不可RemoteCommand
用。
假设以下设置:
foo
是一个跳转主机,并bar
通过其提供对主机的访问localhost:10022
bar
位于网络内,我们可以在其中访问主机rdp
并访问其 RDP 端口 (3389)。我实际上rdp
在我的命令行和配置中给出了 IP ,但我认为只要名称查找有效,使用它的名称是合法的。为简洁起见,我在rdp
这里使用。现在的目标是rdp:3389
通过连接到bar
via jump hostfoo
并将其转发到localhost:33389
我正在调用的本地机器上来获得访问权限ssh bar
。
[local:33389] --> {foo} --> {bar} --> [rdp:3389]
Run Code Online (Sandbox Code Playgroud)
插曲
我以前用 PuTTY 解决了这个问题,如下所示:
foo
与本地转发的连接并配置本地转发-L 33389:localhost:33389
,从而将localhost:33389
本地计算机绑定到localhost:33389
on foo
。bar
位于由通过ssh -L 33389:rdp:3389 -A bar
。Host bar
在 foo
内部配置.ssh/config
为连接到localhost:10022
并最终bar
通过跳转主机。PuTTY 配置就像一个魅力,但它依赖于要执行的远程命令。虽然外壳别名将是解决此问题的一种方法,但我想知道是否有办法将所有内容保存在ssh_config(5)
我的客户端使用的内部,使用ProxyCommand
?
上面 PuTTY 配置的粗略等价物是这样的:
ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 -p 10022 localhost
Run Code Online (Sandbox Code Playgroud)
或者,所提供Host bar
的配置上foo
要经过localhost:10022
的foo
:
ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 bar
Run Code Online (Sandbox Code Playgroud)
这似乎完成了工作。
但是,当然,这已经足够了,而且能够将所有这些都放入配置文件中并ssh bar
在本地机器上简单地输入会更简洁。
随着 RemoteCommand
在OpenSSH的7.6推出,这似乎是相当简单:
Host bar
HostName foo
RemoteCommand ssh -L 33389:rdp:3389 -A -p 10022 localhost
LocalForward 33389 localhost:33389
Run Code Online (Sandbox Code Playgroud)
...这应该大致转化为ssh
上面显示的调用。但如前所述,我使用的是较旧的(打包的)OpenSSH 版本,不支持该RemoteCommand
节。
这是似乎最接近我想要实现的目标的尝试。
Host bar
HostName localhost
Port 10022
ProxyCommand ssh -L 33389:localhost:33389 -W %h:%p foo
LocalForward 33389 rdp:3389
Run Code Online (Sandbox Code Playgroud)
这个想法是在本地机器上我将简单地调用ssh bar
. 事实上,它的工作原理是我最终出现在 的 shell 提示符下bar
,但端口转发根本不起作用。而sudo lsof -i|grep 3389
在本地机器上给我:
ssh 15271 accden 6u IPv6 7933201 0t0 TCP localhost:33389 (LISTEN)
ssh 15271 accden 7u IPv4 7933202 0t0 TCP localhost:33389 (LISTEN)
Run Code Online (Sandbox Code Playgroud)
在跳转主机上,我看不到任何包含3389
.
由于ProxyCommand
建立了与 的连接,foo
并且我正在LocalForward
为与 的连接提供一个bar
,我希望这能正常工作。
我究竟做错了什么?
目标是用于ssh bar
连接到本地计算机并bar
同时使其rdp:3389
在本地计算机上可用localhost:33389
。调整ssh_config(5)
本地机器上的文件foo
是允许的。但是,传递远程命令不是有效的答案。
A.B*_*A.B 12
首先,根据您的设置,什么会起作用,无论如何都需要两个 ssh:
Host foo
LocalForward 10022:bar:22
Host bar
Hostname localhost
Port 10022
LocalForward 33389 rdp:3389
term1$ ssh foo # or use ssh -f -N -o ExitOnForwardFailure=yes foo for background task
term2$ ssh bar
Run Code Online (Sandbox Code Playgroud)
你真正需要的不是 RemoteCommand 而是 ProxyJump,它真正简化了你的配置,目标只有:
ssh -L 33389:rdp:3389 -J foo bar
Run Code Online (Sandbox Code Playgroud)
或等效(仅)配置:
Host bar
ProxyJump foo
LocalForward 33389 rdp:3389
Run Code Online (Sandbox Code Playgroud)
需要零中间端口。
不幸的是,ProxyJump 仅从 openssh 7.3 开始可用
但它很容易被ProxyCommand
-W
您之前使用的/组合替换。
ssh -L 33389:rdp:3389 -o 'ProxyCommand=ssh foo -W %h:%p' bar
Run Code Online (Sandbox Code Playgroud)
或作为配置文件:
Host bar
ProxyCommand ssh -W %h:%p foo
LocalForward 33389 rdp:3389
Run Code Online (Sandbox Code Playgroud)
仍然有两个 ssh 正在运行:隐藏的一个是作为ProxyCommand
参数仍然在本地主机上运行的一个,它使用一对管道与主 ssh 进行链接,而不是额外的 tcp 端口。尝试让中间主机参与端口转发是不安全的或者会发生冲突(foo 的其他用户可以访问隧道或使用相同的端口),并且容易出错。如果可能,隧道末端应始终保留在客户端主机上,在那里可以完全控制。中间隧道要么不存在,要么指向下一个 ssh 入口点(-W
这里是 的用法)。