ssh -L转发多个端口

时间:2015-04-29 07:24:40

标签: ssh port portforwarding

我目前正在运行一堆:

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

其中IP是安全机器的目标,而PORT代表我正在转发的端口。

这是因为我使用了大量的应用程序,如果没有这种转发我无法访问。执行此操作后,我可以通过localhost:PORT访问。

现在出现的主要问题是我实际上有4个这样的端口需要转发。

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

如果我能做的话:

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

然后那确实会有所帮助。

有没有办法让这样做更容易?

13 个答案:

答案 0 :(得分:122)

在同一命令中再次使用-L选项。每次都有不同的端口。

答案 1 :(得分:63)

正是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

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

希望这有帮助。

答案 2 :(得分:15)

您可以使用以下bash功能(只需将其添加到~/.bashrc):

function pfwd {
  for i in ${@:2}
  do
    echo Forwarding port $i
    ssh -N -L $i:localhost:$i $1 &
  done  
}

用法示例:

pfwd hostname {6000..6009}

答案 3 :(得分:6)

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~16009

一样访问hostname:6000~6009

答案 4 :(得分:6)

在我的公司中,我和我的团队成员都需要访问不可访问的“目标”服务器的3个端口,因此我创建了一个永久隧道(该隧道可以运行无限地在后台运行,请参见从可访问服务器到目标服务器的参数-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服务)就我而言)。

答案 5 :(得分:1)

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

情况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的远程工作计算机,最后登录到远程工作。主机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可以是随机数,但here中列出的通用端口号除外。在情况1中,port_A和port_B可以相同,以简化过程。

答案 6 :(得分:1)

对于通过 同一主机 转发多个端口的用户,可以在其〜/ .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 :(得分:1)

这是从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"
}

答案 8 :(得分:1)

另一种方法是使用 ssh 标志告诉 -D 作为 SOCKS 代理工作。

这样,只要客户端应用程序能够通过 SOCKS 代理(或使用诸如 socksify 之类的东西),您就可以通过 ssh 服务器连接到任何可访问的远程网络地址/端口。

答案 9 :(得分:0)

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

pip install loco

loco listen SSHINFO -r 5000 -r 7000

答案 10 :(得分:0)

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

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

答案 11 :(得分:0)

首先可以通过xargs -P 0使用并行执行来完成。

创建一个用于绑定端口的文件,例如

localhost:8080:localhost:8080
localhost:9090:localhost:8080

然后运行

xargs -P 0  -I xxx ssh -vNTCL xxx <REMOTE>  < port-forward

或者你可以做一个单线

echo localhost:{8080,9090} | tr ' ' '\n' | sed 's/.*/&:&/' | xargs -P 0 -I xxx ssh -vNTCL xxx <REMOTE>

优点 独立的 ssh 端口转发,它们是独立的 == 避免单点故障
缺点 每个 ssh 端口转发都是单独分叉的,不知何故效率不高


第二可以使用 bash 中的大括号扩展特性

echo "ssh -vNTC $(echo  localhost:{10,20,30,40,50} | perl -lpe 's/[^ ]+/-L $&:$&/g') <REMOTE>"
# output
ssh -vNTC -L localhost:10:localhost:10 -L localhost:20:localhost:20 -L localhost:30:localhost:30 -L localhost:40:localhost:40 -L localhost:50:localhost:50 <REMOTE>

真实例子

echo "-vNTC $(echo localhost:{8080,9090} | perl -lpe 's/[^ ]+/-L $&:$&/g') gitlab" | xargs ssh

80809090 转发到 gitlab 服务器。

优点一个叉==高效
缺点通过关闭此进程 (ssh) 关闭所有转发 == 单点故障

答案 12 :(得分:-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.