更新

更新

通过 SSH 隧道传输数据非常简单:

ssh -D9999 [email protected]

在您的上设置端口 9999localhost作为到 的隧道example.com,但我有一个更具体的需求:

  • 我正在本地工作localhost
  • host1可以访问localhost
  • host2仅接受来自host1
  • 我需要创建一个从localhost到的隧道host2

实际上,我想创建一个“多跳” SSH 隧道。我该怎么做?理想情况下,我希望无需成为超级用户即可完成此操作任何机器。

答案1

你基本上有三种可能性:

  1. 隧道从localhosthost1:

    ssh -L 9999:host2:1234 -N host1
    

    如上所述,从host1到 的连接host2将不安全。

  2. 隧道从localhosthost1和 从host1host2

    ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2
    

    这将打开一个从localhost到 的隧道host1和另一个从host1到 的隧道。但是上的任何人都可以使用 到端口host2。这可能是也可能不是问题。9999host2:1234host1

  3. 隧道从localhosthost1和 从localhosthost2

    ssh -L 9998:host2:22 -N host1
    ssh -L 9999:localhost:1234 -N -p 9998 localhost
    

    这将打开一个从localhost到 的隧道host1,通过该隧道可以使用 上的 SSH 服务host2。然后通过第一个隧道打开第二个从localhost到 的隧道host2

host1通常情况下,我会选择选项 1。如果到的连接host2需要保护,则选择选项 2。选项 3 主要用于访问host2只能从其host2自身访问的服务。

答案2

有一个ProxyCommand很好的答案,解释了SSH 配置指令的用途

将其添加到您的~/.ssh/config(请参阅man 5 ssh_config详细信息):

Host host2
  ProxyCommand ssh host1 -W %h:%p

然后ssh host2会自动建立隧道host1(也适用于X11转发等)。

这也适用于整个类别的主机,例如通过域标识的主机:

Host *.mycompany.com
  ProxyCommand ssh gateway.mycompany.com -W %h:%p

更新

OpenSSH 7.3 引入指令ProxyJump,将第一个例子简化为

Host host2
  ProxyJump host1

答案3

OpenSSH v7.3 及更高版本支持一个-J开关和一个ProxyJump选项,允许一个或多个以逗号分隔的跳转主机,因此,您现在只需执行以下操作:

ssh -J jumpuser1@jumphost1,jumpuser2@jumphost2,...,jumpuserN@jumphostN user@host

答案4

阅读完以上内容并将所有内容整合在一起后,我创建了以下 Perl 脚本(将其保存为 /usr/bin 中的 mssh 并使其可执行):

#!/usr/bin/perl

$iport = 13021;
$first = 1;

foreach (@ARGV) {
  if (/^-/) {
    $args .= " $_";
  }
  elsif (/^((.+)@)?([^:]+):?(\d+)?$/) {
    $user = $1;
    $host = $3;
    $port = $4 || 22;
    if ($first) {
      $cmd = "ssh ${user}${host} -p $port -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
      $args = '';
      $first = 0;
    }
    else {
      $cmd .= " -L $iport:$host:$port";
      push @cmds, "$cmd -f sleep 10 $args";
      $cmd = "ssh ${user}localhost -p $iport -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no";
      $args = '';
      $iport ++;
    }
  }
}
push @cmds, "$cmd $args";

foreach (@cmds) {
  print "$_\n";
  system($_);
}

用法:

要通过 HOSTA 和 HOSTB(同一用户)访问 HOSTC:

mssh HOSTA HOSTB HOSTC

要通过 HOSTA 和 HOSTB 访问 HOSTC 并使用非默认 SSH 端口号和不同的用户:

mssh user1@HOSTA:1234 user2@HOSTB:1222 user3@HOSTC:78231

要通过 HOSTA 和 HOSTB 访问 HOSTC 并使用 X-forwarding:

mssh HOSTA HOSTB HOSTC -X

要通过 HOSTA 和 HOSTB 访问 HOSTC 上的端口 8080:

mssh HOSTA HOSTB -L8080:HOSTC:8080

相关内容