通过 SSH 隧道传输数据非常简单:
ssh -D9999 [email protected]
在您的上设置端口 9999localhost
作为到 的隧道example.com
,但我有一个更具体的需求:
- 我正在本地工作
localhost
host1
可以访问localhost
host2
仅接受来自host1
- 我需要创建一个从
localhost
到的隧道host2
实际上,我想创建一个“多跳” SSH 隧道。我该怎么做?理想情况下,我希望无需成为超级用户即可完成此操作任何机器。
答案1
你基本上有三种可能性:
隧道从
localhost
至host1
:ssh -L 9999:host2:1234 -N host1
如上所述,从
host1
到 的连接host2
将不安全。隧道从
localhost
到host1
和 从host1
到host2
:ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2
这将打开一个从
localhost
到 的隧道host1
和另一个从host1
到 的隧道。但是上的任何人都可以使用 到端口host2
。这可能是也可能不是问题。9999
host2:1234
host1
隧道从
localhost
到host1
和 从localhost
到host2
: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