ssh -L转发多个端口


128

我目前正在运行一堆:

sudo ssh -L PORT:IP:PORT root@IP

其中IP是受保护机器的目标,而PORT表示我正在转发的端口。

这是因为我使用了很多应用程序,如果没有此转发,便无法访问。完成此操作后,我可以通过访问localhost:PORT

现在出现了主要问题,实际上我必须转发其中四个端口。

我的解决方案是打开4个外壳,并不断向后搜索我的历史记录,以准确查找需要转发的端口等,然后运行此命令-每个外壳中都有一个(必须填写密码等)。

如果我能做些什么:

sudo ssh -L PORT1+PORT2+PORT+3:IP:PORT+PORT2+PORT3 root@IP

那将已经真的有帮助。

有没有一种方法可以使此操作更容易?

Answers:


195

-L可以在同一命令中多次指定该选项。每次使用不同的端口。


20
起初我不明白这个答案。因此,如果有人遭受同样的痛苦,请在此处发布示例。作者的意思是“ ssh -L port0:ip:port0 -L port1:ip:port1 ...”
Mong H. Ng

96

正是NaN回答的问题,您指定了多个-L参数。我一直都这样做。这是多端口转发的示例:

ssh remote-host -L 8822:REMOTE_IP_1:22 -L 9922:REMOTE_IP_2:22

注意:这与 -L localhost:8822:REMOTE_IP_1:22您未指定localhost

现在,您可以(从另一个终端)执行以下操作:

ssh localhost -p 8822

连接到REMOTE_IP_1端口22

同样

ssh localhost -p 9922

连接到REMOTE_IP_2端口22

当然,如果您有许多不同的主机/端口要转发到某些特定主机/端口,则没有什么可以阻止您将其包装到脚本中或使其自动化。

希望这可以帮助。


Nan的答案的极大补充。谢谢。
AFP_555 '18

1
请注意以下事项:“注意:如果您未指定localhost,则它与-L localhost:8822:REMOTE_IP_1:22相同。” 仅当GatewayPorts设置为“ no”时,这才是正确的,这是默认设置。但是,如果不考虑其含义,则应验证该设置,或者更明确的是,使用“ -L localhost:8822 ...”。
大卫,

我同意@David By default, anyone (even on different machines) can connect to the specified port on the SSH client machine. However, this can be restricted to programs on the same host by supplying a bind address: ssh -L 127.0.0.1:80:intra.example.com:80 gw.example.com ssh.com/ssh/tunneling/example
Karl Pokus


12

对于通过同一主机转发多个端口用户,可以在其〜/ .ssh / config中设置类似的内容

Host all-port-forwards Hostname 10.122.0.3 User username LocalForward PORT_1 IP:PORT_1 LocalForward PORT_2 IP:PORT_2 LocalForward PORT_3 IP:PORT_3 LocalForward PORT_4 IP:PORT_4

变得简单ssh all-port-forwards了。


我喜欢这种方法。
宝马

7

jbchichoko和yuval提供了可行的解决方案。但是jbchichoko的答案在功能上不是灵活的答案,并且yuval的答案打开的隧道无法关闭,ctrl+c因为它在后台运行。下面给出解决两个缺陷的解决方案:

~/.bashrc或中定义函数~/.zshrc

# fsshmap multiple ports
function fsshmap() {
  echo -n "-L 1$1:127.0.0.1:$1 " > $HOME/sh/sshports.txt
  for ((i=($1+1);i<$2;i++))
  do
    echo -n "-L 1$i:127.0.0.1:$i " >> $HOME/sh/sshports.txt
  done
  line=$(head -n 1 $HOME/sh/sshports.txt)
  cline="ssh "$3" "$line
  echo $cline
  eval $cline
}

运行该函数的示例:

fsshmap 6000 6010 hostname

该示例的结果:

您可以访问127.0.0.1:16000~16009hostname:6000~6009


2

通过端口转发登录服务器的好处之一是便于使用Jupyter Notebook。该链接提供了一个很好的说明。在这里,我想做一些总结和扩展,以供大家参考。

情况1.从名为Host-A的本地计算机(例如您自己的笔记本电脑)登录到名为Host-B的远程工作计算机。

ssh user@Host-B -L port_A:localhost:port_B
jupyter notebook --NotebookApp.token='' --no-browser --port=port_B

然后,您可以打开浏览器并输入:http:// localhost:port_A /在Host-B上进行工作,但在Host-A中看到它。

情况2.从名为Host-A的本地计算机(例如您自己的笔记本电脑)登录到名为Host-B的远程登录计算机,然后从那里登录到名为Host-C的远程工作计算机。对于大学中的大多数分析服务器来说通常是这种情况,可以通过使用两个ssh -L与相连的服务器来实现-t

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C
jupyter notebook --NotebookApp.token='' --no-browser --port=port_C

然后,您可以打开浏览器并输入:http:// localhost:port_A /在Host-C上进行工作,但在Host-A中可以看到它。

情况3.从名为Host-A的本地计算机(例如您自己的笔记本电脑)登录到名为Host-B的远程登录计算机,然后从那里登录到名为Host-C的远程工作计算机,最后登录到远程工作计算机Host-B。 D.通常不是这种情况,但可能会在某些时候发生。它是情况2的扩展,相同的逻辑可以应用于更多机器。

ssh -L port_A:localhost:port_B user@Host-B -t ssh -L port_B:localhost:port_C user@Host-C -t ssh -L port_C:localhost:port_D user@Host-D
jupyter notebook --NotebookApp.token='' --no-browser --port=port_D

然后,您可以打开浏览器并输入:http:// localhost:port_A /在Host-D上进行工作,但在Host-A中可以看到它。

请注意,port_A,port_B,port_C,port_D可以是随机数,但此处列出的通用端口号除外。在情况1中,port_A和port_B可以相同,以简化过程。


提醒一下,不同服务器上的相同端口是不同的端口。因此,通过指定相同的端口号总是可以使事情变得容易!
Fei Yao

2

在我的公司中,我和我的团队成员都需要访问不可访问的“目标”服务器的3个端口,因此我创建了一个永久隧道(该隧道可以无限期在后台运行,请参阅paras -f-N),从可访问服务器到目标之一。在可访问服务器的命令行上,我执行了:

ssh root@reachableIP -f -N  -L *:8822:targetIP:22  -L *:9006:targetIP:9006  -L *:9100:targetIP:9100

我使用过用户,root但是您自己的用户可以使用。您将必须输入所选用户的密码(即使您已使用该用户连接到可访问的服务器)。

现在,可访问计算机的端口8822对应于目标端口的22端口(用于ssh / PuTTY / WinSCP),而可访问计算机上的端口9006和9100对应于目标端口的相同端口(在我的情况下,它们托管两个Web服务) )。


0

我已经开发了loco来帮助ssh转发。它可用于在同一端口上本地共享远程端口5000和7000:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

0

如果您想要一个在后台运行且易于杀死的简单解决方案,请使用控制套接字

# start
$ ssh -f -N -M -S $SOCKET -L localhost:9200:localhost:9200 $HOST
# stop
$ ssh -S $SOCKET -O exit $HOST

0

这是从Yuval Atzmon那里获得灵感的解决方案。

与初始解决方案相比,它具有一些优点:

  • 首先,它创建一个后台进程,而不是每个端口一个
  • 它生成别名,使您可以杀死隧道
  • 它仅绑定到127.0.0.1,这更加安全

您可以将其用作:

  • tnl your.remote.com 1234
  • tnl your.remote.com {1234,1235}
  • tnl your.remote.com {1234..1236}

最后用杀死他们tnlkill

function tnl {
  TUNNEL="ssh -N "
  echo Port forwarding for ports:
  for i in ${@:2}
  do
    echo " - $i"
    TUNNEL="$TUNNEL -L 127.0.0.1:$i:localhost:$i"
  done
  TUNNEL="$TUNNEL $1"
  $TUNNEL &
  PID=$!
  alias tnlkill="kill $PID && unalias tnlkill"
}

-1

您可以使用此zsh函数(也可能与bash一起使用)(将其放入~/.zshrc):

ashL () {
    local a=() i
    for i in "$@[2,-1]"
    do
        a+=(-L "${i}:localhost:${i}")
    done
    autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NT "$1" "$a[@]"
}

例子:

ashL db@114.39.161.24 6480 7690 7477

ashL db@114.39.161.24 {6000..6050} # Forwards the whole range. This is simply shell syntax sugar.

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.