注意:我使用的 OpenSSH 客户端都位于7.2版本, 所以不行RemoteCommand
可用的。
假设以下设置:
- 机器
foo
是一个跳转主机,并bar
通过其提供对主机的访问localhost:10022
bar
位于网络内,我们可以在其中访问主机rdp
并访问其 RDP 端口 (3389)。实际上,我在命令行和配置中给出了 IPrdp
,但我认为只要名称查找有效,使用其名称就是合法的。为了简洁起见,我rdp
在这里使用。
现在的目标是通过跳转主机rdp:3389
连接来获得访问权限,并将其转发到我调用的本地计算机上。bar
foo
localhost:33389
ssh bar
[local:33389] --> {foo} --> {bar} --> [rdp:3389]
插曲
我之前已经用 PuTTY 解决了这个问题,如下所示:
- 创建到 的连接
foo
并配置本地转发-L 33389:localhost:33389
,从而localhost:33389
将本地计算机绑定到localhost:33389
onfoo
。 - 使用以下远程命令将端口转发到其所在的网络
bar
中ssh -L 33389:rdp:3389 -A bar
。 Host bar
已配置在foo
.ssh/config
连接到并最终通过跳转主机localhost:10022
结束。bar
PuTTY 配置的工作方式就像一个魅力,但它依赖于远程命令来执行。虽然 shell 别名是解决此问题的一种方法,但我想知道是否有一种方法可以将所有内容保留在ssh_config(5)
我的客户使用的内部,使用ProxyCommand
?
上述 PuTTY 配置的大致等效内容如下:
ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 -p 10022 localhost
或者,前提是Host bar
配置为foo
执行localhost:10022
以下操作foo
:
ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 bar
这似乎完成了工作。
当然,这已经足够打字了,如果能把它写下来会更整洁全部进入配置文件并只需ssh bar
在本地计算机上键入即可。
和 RemoteCommand
正如 OpenSSH 7.6 中所介绍的,这似乎相当简单:
Host bar
HostName foo
RemoteCommand ssh -L 33389:rdp:3389 -A -p 10022 localhost
LocalForward 33389 localhost:33389
...这应该大致翻译为ssh
上面显示的调用。但如前所述,我使用的是旧版(打包的)OpenSSH,不支持该RemoteCommand
节。
这是似乎最接近我想要实现的目标的尝试。
Host bar
HostName localhost
Port 10022
ProxyCommand ssh -L 33389:localhost:33389 -W %h:%p foo
LocalForward 33389 rdp:3389
我的想法是,在本地计算机上我将简单地调用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)
在跳转主机上,我看不到任何包含3389
.
由于ProxyCommand
建立了与 的连接foo
,并且我正在LocalForward
为与 的连接提供一个连接bar
,所以我希望这能起作用。
我究竟做错了什么?
目标是用于ssh bar
连接到本地计算机bar
并同时rdp:3389
在本地计算机上可用localhost:33389
。允许调整ssh_config(5)
本地计算机上的文件。foo
不过,传递远程命令并不是一个有效的答案。
答案1
首先,根据您的设置,什么会工作,要求反正两个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
你真正需要的不是RemoteCommand,而是ProxyJump,真正简化你的配置,达到目标仅有的和:
ssh -L 33389:rdp:3389 -J foo bar
或等效(唯一)配置:
Host bar
ProxyJump foo
LocalForward 33389 rdp:3389
需要零中间端口。
不幸的是 ProxyJump 仅从 openssh 7.3 开始可用
但它是轻松替换为ProxyCommand
/-W
组合你之前用过。
ssh -L 33389:rdp:3389 -o 'ProxyCommand=ssh foo -W %h:%p' bar
或作为配置文件:
Host bar
ProxyCommand ssh -W %h:%p foo
LocalForward 33389 rdp:3389
仍然有两个 ssh 正在运行:隐藏的一个是ProxyCommand
仍在本地主机上运行的参数,它使用一对管道与主 ssh 进行链接,而不是额外的 tcp 端口。尝试让中间主机参与端口转发是不安全的或可能发生冲突(foo 的其他用户可以访问隧道或使用相同的端口),并且容易出错。如果可能的话,隧道末端应始终保留在客户端主机上,以便完全控制。中间隧道要么不存在,要么指向下一个 ssh 入口点(这就是-W
此处的用法)。