ssh -L encaminha várias portas


129

Atualmente, estou executando um monte de:

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

em que IP é o destino de uma máquina protegida e PORT representa as portas que estou encaminhando.

Isso ocorre porque eu uso muitos aplicativos que não consigo acessar sem esse encaminhamento. Depois de fazer isso, posso acessar o localhost:PORT.

O principal problema ocorreu agora que na verdade tenho 4 dessas portas que devo encaminhar.

Minha solução é abrir 4 shells e constantemente pesquisar meu histórico para trás para procurar exatamente quais portas precisam ser encaminhadas, etc, e então executar este comando - um em cada shell (tendo que preencher as senhas etc).

Se eu pudesse fazer algo como:

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

então isso já ajudaria muito.

Existe uma maneira de tornar mais fácil fazer isso?

Respostas:


195

A -Lopção pode ser especificada várias vezes no mesmo comando. Cada vez com portas diferentes.


20
No começo eu não entendi essa resposta. Então postando um exemplo aqui caso alguém sofra o mesmo. O autor quis dizer "ssh -L port0: ip: port0 -L port1: ip: port1 ..."
Mong H. Ng

96

Exatamente o que NaN respondeu, você especifica vários argumentos -L. Eu faço isso toda hora. Aqui está um exemplo de encaminhamento de várias portas:

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

Observação : é o mesmo que -L localhost:8822:REMOTE_IP_1:22se você não especificar localhost.

Agora, com isso, você pode agora (de outro terminal) fazer:

ssh localhost -p 8822

para conectar REMOTE_IP_1na porta22

e similarmente

ssh localhost -p 9922

para conectar REMOTE_IP_2na porta22

Claro, não há nada que o impeça de embrulhar isso em um script ou automatizá-lo se você tiver muitos hosts / portas diferentes para encaminhar e para alguns específicos.

Espero que isto ajude.


Ótimo complemento para a resposta de Nan. Obrigado.
AFP_555

1
Tenha cuidado com isso: "Observação: é o mesmo que -L localhost: 8822: REMOTE_IP_1: 22 se você não especificar localhost." Isso só é verdade se a configuração GatewayPorts for 'não', que é reconhecidamente o padrão. Mas considerando as implicações do contrário, você deve verificar a configuração ou, melhor ainda, ser explícito e usar "-L localhost: 8822 ...".
David

Eu concordo com 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 @David ssh.com/ssh/tunneling/example
Karl Pokus

24

Você pode usar a seguinte função bash (basta adicioná-la ao seu ~/.bashrc):

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

Exemplo de uso:

pfwd hostname {6000..6009}

2
Use -fpara correr em segundo plano
Karl Pokus

Ehmmm ... por que você quer fazer dessa forma?
Anton Bessonov

14

Para as pessoas que estão encaminhando várias portas através do mesmo host podem configurar algo assim em seu ~ / .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

e se torna um simples ssh all-port-forwardsafastamento.


Eu gosto dessa abordagem.
BMW

8

jbchichoko e yuval deram soluções viáveis. Mas a resposta de jbchichoko não é uma resposta flexível como uma função, e os túneis abertos pela resposta de yuval não podem ser fechados ctrl+cporque ele funciona em segundo plano. Dou minha solução abaixo, resolvendo as duas falhas:

Definindo uma função em ~/.bashrcou~/.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
}

Um exemplo de execução da função:

fsshmap 6000 6010 hostname

Resultado deste exemplo:

Você pode acessar 127.0.0.1:16000~16009o mesmo quehostname:6000~6009


3

Um dos benefícios de fazer login em um servidor com encaminhamento de porta é facilitar o uso do Jupyter Notebook. Este link fornece uma excelente descrição de como fazer isso. Aqui eu gostaria de fazer um resumo e uma expansão para todos vocês referirem.

Situação 1. Efetue login de uma máquina local chamada Host-A (por exemplo, seu próprio laptop) para uma máquina de trabalho remota chamada Host-B.

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

Em seguida, você pode abrir um navegador e inserir: http: // localhost: port_A / para fazer seu trabalho no Host-B, mas vê-lo no Host-A.

Situação 2. Faça login de uma máquina local chamada Host-A (por exemplo, seu próprio laptop) para uma máquina de login remota chamada Host-B e, a partir daí, faça login na máquina de trabalho remota chamada Host-C. Esse é geralmente o caso da maioria dos servidores analíticos dentro das universidades e pode ser obtido usando dois ssh -Lconectados com -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

Em seguida, você pode abrir um navegador e inserir: http: // localhost: port_A / para fazer seu trabalho no Host-C, mas vê-lo no Host-A.

Situação 3. Faça login de uma máquina local chamada Host-A (por exemplo, seu próprio laptop) em uma máquina de login remota chamada Host-B e, a partir daí, faça login na máquina de trabalho remota chamada Host-C e, finalmente, faça o login na máquina de trabalho remota Host- D. Normalmente não é esse o caso, mas pode acontecer algum dia. É uma extensão da Situação 2 e a mesma lógica pode ser aplicada em mais máquinas.

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

Em seguida, você pode abrir um navegador e inserir: http: // localhost: port_A / para fazer seu trabalho no Host-D, mas vê-lo no Host-A.

Observe que port_A, port_B, port_C, port_D podem ser números aleatórios, exceto os números de porta comuns listados aqui . Na Situação 1, port_A e port_B podem ser iguais para simplificar o procedimento.


Um lembrete, a mesma porta em servidores diferentes são portas diferentes. Portanto, pode sempre tornar as coisas mais fáceis especificando um número de porta idêntico!
Fei Yao

3

Na minha empresa, eu e os membros da minha equipe precisamos acessar 3 portas de um servidor "alvo" não alcançável, então criei um túnel permanente (que é um túnel que pode ser executado em segundo plano indefinidamente, consulte parâmetros -fe -N) de um servidor alcançável para o alvo. Na linha de comando do servidor alcançável, executei:

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

Usei usuário, rootmas seu próprio usuário funcionará. Você terá que inserir a senha do usuário escolhido (mesmo se já estiver conectado ao servidor alcançável com esse usuário).

Agora a porta 8822 da máquina alcançável corresponde à porta 22 da máquina de destino (para ssh / PuTTY / WinSCP) e as portas 9006 e 9100 na máquina alcançável correspondem às mesmas portas da máquina de destino (elas hospedam dois serviços da web no meu caso )


1

Desenvolvi o loco para obter ajuda com o encaminhamento de ssh. Ele pode ser usado para compartilhar as portas 5000 e 7000 no local remoto nas mesmas portas:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

1

Se você quiser uma solução simples que rode em segundo plano e seja fácil de eliminar - use um soquete de controle

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

1

Aqui está uma solução inspirada na de Yuval Atzmon.

Tem alguns benefícios em relação à solução inicial:

  • primeiro, ele cria um único processo em segundo plano e não um por porta
  • ele gera o alias que permite que você mate seus túneis
  • ele se liga apenas a 127.0.0.1 que é um pouco mais seguro

Você pode usá-lo como:

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

E, finalmente, mate todos eles com 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

Você pode usar esta função zsh (provavelmente funciona com bash também) (colocá-la ~/.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[@]"
}

Exemplos:

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.