这似乎是一件简单的事情,但我被困住了。
在 Ubuntu 机器上,通过 ssh 进入特定REMOTE_HOST
机器,直到现在我都可以
ssh REMOTE_HOST
正如预期的那样(键都设置好)。现在,我被迫通过一台特定的BRIDGE_HOST
机器设置一个 ssh 隧道
ssh -L 2222:REMOTE_HOST:22 BRIDGE_HOST -N -f
然后我可以使用 ssh 到 REMOTE_HOST
ssh -p 2222 localhost
尽管事情有点复杂,但这工作得很好。这里有几个问题:
localhost
运行 OpenSSH_7.2p2 所以没有 -J / ProxyJump 选项,如果这有帮助的话。我无法更新 OpenSSH,或者至少我宁愿避免它。我必须
REMOTE_HOST
使用密码登录,所以我需要使用sshpass
(请不要告诉我不应该,我无法控制)。所以ssh
上面的第一个命令并不完全如图所示,而是更复杂;然而,我认为它没有增加任何内容来显示更复杂的版本。但这是我的一个限制,我担心会阻止一些更清洁的解决方案。没有外壳,
REMOTE_HOST
据我所知(或我理解)我只被允许设置隧道。
无论如何,我可以通过这两个步骤 ssh 进入REMOTE_HOST
,但我想做的是隐藏所有这些.ssh/config
以使其透明(尤其是对于 CVS,见下文)。这样的事情似乎很好:
Host REMOTE_HOST
Hostname localhost
Port 2222
ProxyCommand tcsh -c "ssh -L 2222:REMOTE_HOST:22 BRIDGE_HOST -N -f; nc %h %p"
如果我现在跑
ssh REMOTE_HOST
我可以 ssh 进入REMOTE_HOST
,就好像隧道不存在一样。伟大的。
复杂性(和问题)的最终来源是我想将此 ssh 连接也用于 CVS。从 CVS 方面来看,一切都设置得很好(例如,当我不必使用它时它可以工作BRIDGE_HOST
)。如果我现在跑
cvs up
在适当的目录中,一切似乎都运行良好......但是该cvs
命令在正确完成其工作后永远不会终止。我似乎明白这是因为创建隧道的 ssh 最终仍在运行。我很乐意杀死它,但我不知道如何杀死它。相关地,请注意,如果我省略ProxyCommand
了 in.ssh/config
并且之前手动设置了隧道,那么一切都很好,CVS 运行顺利(并终止)。我会忘记ProxyCommand
并设置,autossh
但我知道它不适用于sshpass
. 我可以设置一个 cron 作业或一些手动保持隧道活动的脚本,但我认为(或希望)必须有更好的方法......
实现我想要的结果的正确、最简单和最干净的方法是什么?也就是说,cvs
尽管插入了BRIDGE_HOST
我无法控制的内容,但仍然像往常一样简单地使用?
由于我无法理解如何在 CVS 完成后终止隧道,并且由于我不能使用
autossh
withsshpass
,所以我决定添加一个 cron 作业。我首先创建了一个小脚本,将网上找到的一堆食谱和想法组合在一起。这是脚本:
本质上,它首先杀死自己的任何其他副本,然后杀死同一端口上的现有隧道并启动所需的隧道,并在任何时候永远重复此过程
ssh
死亡。这是一种穷人版本的autossh
.连同这个
.ssh/config
文件这使得
ssh
(和 CVS)表现得好像 REMOTE_HOST 仍然可以直接访问。该脚本可以通过以下方式方便地调用
cron
:每天凌晨 4:30 重新启动可能完全没有必要,但不知何故似乎是安全的事情,以防出现问题。
与 ProxyJump 几乎等效的是:
这实际上是 ProxyJump 在后台所做的。两者之间唯一真正的区别是 ProxyJump 会自动将某些其他选项(例如详细
-v
模式)复制到所有涉及的连接。如果桥接服务器允许使用创建隧道,
-L
那么它会自动允许-W
(并且-D
也允许),因为它们都使用相同的 SSHv2 通道类型;服务器不知道区别。这也应该与 sshpass 作为命令一起使用。或者,为了避免多次重新输入密码,您可以对桥接主机使用连接多路复用:
到 BRIDGE_HOST 的第一个连接将在后台留下一个进程;或者,您可以使用
ssh -fNM BRIDGE_HOST
(如果需要,可以使用 sshpass)启动后台进程,未来ssh -w ... BRIDGE_HOST
将自动使用该进程。在您的 tcsh+nc 示例中,该命令最好写为: