通过中间机转发SSH流量


110

SSH隧道使我感到非常困惑。我想知道我是否可以在Linux中做到这一点。

我有3台机器。

A. My local machine at home.
B. Machine at work that I can SSH into (middle man).
C. My desktop at work that I can only SSH into from machine B.

所以我可以从A-> B和B-> C进行SSH,但不能从A-> C进行SSH。

有没有一种方法可以设置从A到B的SSH隧道,所以当我运行其他SSH命令时,它们只能在本地计算机A上运行?我基本上是试图从工作到家克隆一个git repo(并且我不能在机器B上安装git)。

另外,一旦设置好了。我也将如何取消设置呢?


我相信某个地方有一个重复的问题,但是今天我的搜索能力很弱。
quack quixote 2010年



如果您在计算机A上运行Linux,请使用名为sshuttle的工具,该工具可让您通过A-> B隧道有选择地转发C的所有流量(假设C从B可见)。
joat

Answers:


128

将其放置.ssh/config在hostA上的文件中(有关详细信息,请参见man 5 ssh_config):

# .ssh/config on hostA:
Host hostC
    ProxyCommand ssh hostB -W %h:%p

现在,以下命令将自动通过hostB隧道传输

hostA:~$ ssh hostC

您可能希望添加诸如此类的选项-oCiphers=arcfour-oClearAllForwardings=yes加快处理速度,因为ssh内部包装在ssh计算上会更加昂贵,并且需要付出额外的努力,并且在隧道传输已加密的流量时,包装器不必像以前那样安全。


如果您使用的OpenSSH早于5.3,则该-W选项不可用。在这种情况下,您可以使用netcat(nc)实现上述功能:

ProxyCommand ssh hostB nc %h %p  # or netcat or whatever you have on hostB

1
这太棒了!谢谢。这解决了过去两天来一直困扰我的问题:hostC坐在防火墙后面,并拥有我想从hostA访问的数据,hostA是可以在世界任何地方使用的笔记本电脑。hostB也位于与hostC相同的防火墙后面,但是它具有向世界开放的SSH端口。因此,我可以从hostC-> hostB SSH。我在hostC和hostB之间设置了反向SSH隧道,因此我也可以从hostB-> hostC SSH(通过localhost转发)。用你的把戏,我可以从hostA-> hostC去!它可以与OSX上的SCP和Fugu无缝协作!谢谢!
AndyL'3

-W应该使用该选项而不是该nc选项。
vy32 2015年

应该支持哪种SSH -W,仅在hostA(源)上的一个,还是在hostB(中间机)上的一个?
gioele,2015年

有关信息,如果您有多个主机,则需要通过同一个主机进行访问hostB,因此可以在Host hostC上方声明多行,ProxyCommand从而可以非常轻松地通过中间服务器访问多个主机。
fduff

7

编辑:这是错误的方法。请参阅以太坊的答案。这个答案会起作用,但是可能不太安全,而且绝对不太好。

听起来您想要以下解决方案:

ssh -L localhost:22:machinec:22 machineb

这将使您获得成功machineb。别管它了;最小化终端窗口。

现在,只要你做的SSH连接localhost,你实际上将连接到machinec通过machineb。完成隧道操作后,只需关闭运行上述命令的终端即可。

请注意,您需要超级用户特权才能运行该命令。


+1感谢韦斯利。这是真正的ssh隧道答案。这是一篇关于它的文章:securityfocus.com/infocus/1816
Larry K

3
总的来说,这是很邪恶的……但是我不得不使用古老版本的OpenSSH或其他ssh客户端来做到这一点。您可以选择一些较高的端口,例如8022:这样,它不会干扰localhost上的任何ssh服务,并且不需要以root用户身份运行。只需添加-p 8022到您的ssh命令。而使用git则很容易死:使用URI ssh://localhost:8022/path/to/repo.git
短暂

3

听起来您想要在A上使用shell别名,从而导致ssh在C上发生

  1. 我假设在A上,您可以输入ssh me @ b“ ssh me @ c主机名”并返回“ C”
  2. 创建一个别名sshc,它将sshc foo扩展为ssh me @ b“ ssh me @ c foo”
  3. 有关创建别名的确切语法,请访问superuser.com。

1
-t如果要使用交互式外壳,则可能必须添加到外部ssh的选项中,因为ssh假定-T已给出命令。
短暂

1

对于交互式shell,可以使用以下简单命令:

ssh -J <user>@<hostB> <user>@<hostC>

-J选项用于jump


0

如果您的雇主提供了VPN,我建议您改用它。

这样,您就不必专门配置任何应用程序(甚至是ssh),并且可以看到防火墙后面的任何计算机。此外,您的所有流量都将由VPN软件进行加密,这将为任何无意或故意未加密的流量增加安全性。


6
有时是VPN,这就是我们需要这些技巧的原因……
路易(Louis)

0

YASS另一个简单的解决方案

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost
  • 第一条命令打开与HostB的ssh连接,并告诉HostB将连接从localhost:2222转发到HostC:22
  • -f建立连接后,该参数告诉SSH进入后台
  • 第二个命令只是打开一个到localhost:2222的客户端连接
  • 不需要选件HostKeyAlias,但可以帮助防止连接到错误的主机
  • 注意:sleep 10在第二个ssh命令使用转发的端口之前,需要使用该命令来保持连接。然后,当第二条SSH离开转发端口时,第一条SSH将关闭。

您现在可以运行后续的ssh会话:

ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost

变体:

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -M -S ~/.ssh/ssh_HostC22userOnC.sock -o HostKeyAlias=HostC -p 2222 userOnC@localhost

随后的ssh会话可以通过运行来打开:

ssh -S ~/.ssh/ssh_HostC22userOnC.sock userOnC@localhost

使用-M和-S参数的主要优点是,从HostA到HostC仅打开一个连接,后续会话将不再进行身份验证,并且运行速度更快。


0

特殊情况,混合nix平台:

  hostA(linux)-> HostB(solaris)-> HostC(linux)

如果需要在hostC上使用X应用程序,并且中间跃点在Solaris盒上...在这种情况下,我在ProxyCommand上找到了所需的netcat(nc),如下所示:

hostA:〜$ vi .ssh / config:

主机hostC
    ProxyCommand ssh hostB nc%h%p#其中nc是netcat

然后自动隧道工作:

hostA:〜$ ssh hostC

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.