ssh -L inoltra più porte


129

Attualmente sto gestendo un gruppo di:

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

dove IP è l'obiettivo di una macchina protetta e PORT rappresenta le porte che sto inoltrando.

Questo perché utilizzo molte applicazioni a cui non posso accedere senza questo inoltro. Dopo aver eseguito questa operazione, posso accedere tramite localhost:PORT.

Il problema principale si è verificato ora che ho effettivamente 4 di queste porte che devo inoltrare.

La mia soluzione è aprire 4 shell e cercare costantemente la mia cronologia all'indietro per cercare esattamente quali porte devono essere inoltrate ecc., Quindi eseguire questo comando, uno in ciascuna shell (dover inserire le password ecc.).

Se solo potessi fare qualcosa come:

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

allora questo sarebbe già di grande aiuto.

C'è un modo per renderlo più facile?

Risposte:


195

L' -Lopzione può essere specificata più volte all'interno dello stesso comando. Ogni volta con porte diverse.


20
All'inizio non ho capito questa risposta. Quindi postando un esempio qui nel caso qualcuno soffra lo stesso. L'autore significava "ssh -L port0: ip: port0 -L port1: ip: port1 ..."
Mong H. Ng

96

Esattamente quello che ha risposto NaN , specifichi più argomenti -L. Lo faccio tutto il tempo. Ecco un esempio di inoltro multiporta:

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

Nota : è come -L localhost:8822:REMOTE_IP_1:22se non specifichi localhost.

Ora con questo, ora puoi (da un altro terminale) fare:

ssh localhost -p 8822

a cui connettersi REMOTE_IP_1sulla porta22

e allo stesso modo

ssh localhost -p 9922

a cui connettersi REMOTE_IP_2sulla porta22

Naturalmente, non c'è nulla che ti impedisca di avvolgerlo in uno script o di automatizzarlo se hai molti host / porte diversi da inoltrare e verso alcuni specifici.

Spero che questo ti aiuti.


Ottimo complemento alla risposta di Nan. Grazie.
AFP_555

1
Fai attenzione a questo: "Nota: è uguale a -L localhost: 8822: REMOTE_IP_1: 22 se non specifichi localhost." Questo è vero solo se l'impostazione GatewayPorts è "no", che è certamente l'impostazione predefinita. Ma considerando le implicazioni in caso contrario, dovresti verificare l'impostazione o, meglio ancora, essere esplicito e utilizzare "-L localhost: 8822 ...".
David

Sono d'accordo con @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

24

Puoi usare la seguente funzione bash (aggiungila al tuo ~/.bashrc):

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

Esempio di utilizzo:

pfwd hostname {6000..6009}

2
Utilizzare -fper eseguire in background
Karl Pokus

Ehmmm ... perché vuoi farlo in quel modo?
Anton Bessonov

14

Per le persone che stanno inoltrando più porte attraverso lo stesso host possono impostare qualcosa di simile nel loro ~ / .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 diventa una semplice ssh all-port-forwardsvia.


Mi piace questo approccio.
BMW

8

jbchichoko e yuval hanno fornito soluzioni praticabili. Ma la risposta di jbchichoko non è una risposta flessibile come funzione, e i tunnel aperti dalla risposta di yuval non possono essere chiusi ctrl+cperché vengono eseguiti in background. Fornisco la mia soluzione di seguito risolvendo entrambi i due difetti:

Definire una funzione in ~/.bashrco~/.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
}

Un esempio di esecuzione della funzione:

fsshmap 6000 6010 hostname

Risultato di questo esempio:

Puoi accedere 127.0.0.1:16000~16009allo stesso dihostname:6000~6009


3

Uno dei vantaggi di accedere a un server con il port forwarding è facilitare l'uso di Jupyter Notebook. Questo collegamento fornisce un'eccellente descrizione di come farlo. Qui vorrei fare un riassunto e un'espansione per farvi riferimento a tutti voi ragazzi.

Situazione 1. Effettuare l'accesso da una macchina locale denominata Host-A (ad esempio il proprio laptop) a una macchina di lavoro remota denominata Host-B.

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

Quindi puoi aprire un browser e inserire: http: // localhost: port_A / per fare il tuo lavoro su Host-B ma vederlo in Host-A.

Situazione 2. Accedere da una macchina locale denominata Host-A (ad es. Il proprio laptop) a una macchina di accesso remota denominata Host-B e da lì accedere alla macchina di lavoro remota denominata Host-C. Questo di solito è il caso della maggior parte dei server analitici all'interno delle università e può essere ottenuto utilizzando due ssh -Lconnessi con -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

Quindi puoi aprire un browser e inserire: http: // localhost: port_A / per fare il tuo lavoro su Host-C ma vederlo in Host-A.

Situazione 3. Accedi da una macchina locale denominata Host-A (ad es. Il tuo laptop) a una macchina di accesso remota denominata Host-B e da lì accedi alla macchina di lavoro remota denominata Host-C e infine accedi alla macchina di lavoro remota Host- D. Questo non è di solito il caso, ma potrebbe accadere a volte. È un'estensione della Situazione 2 e la stessa logica può essere applicata su più macchine.

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

Quindi puoi aprire un browser e inserire: http: // localhost: port_A / per fare il tuo lavoro su Host-D ma vederlo in Host-A.

Nota che port_A, port_B, port_C, port_D possono essere numeri casuali tranne i numeri di porta comuni elencati qui . Nella situazione 1, port_A e port_B possono essere gli stessi per semplificare la procedura.


Un promemoria, la stessa porta su server diversi sono porte diverse. Quindi potrebbe sempre rendere le cose più facili specificando un numero di porta identico!
Fei Yao

3

Nella mia azienda sia io che i membri del mio team abbiamo bisogno di accedere a 3 porte di un server "target" non raggiungibile, quindi ho creato un tunnel permanente (che è un tunnel che può essere eseguito in background indefinitamente, vedi parametri -fe -N) da un server raggiungibile a quello di destinazione. Sulla riga di comando del server raggiungibile ho eseguito:

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

Ho usato user rootma il tuo utente funzionerà. Dovrai inserire la password dell'utente scelto (anche se sei già connesso al server raggiungibile con quell'utente).

Ora la porta 8822 della macchina raggiungibile corrisponde alla porta 22 di quella di destinazione (per ssh / PuTTY / WinSCP) e le porte 9006 e 9100 sulla macchina raggiungibile corrispondono alle stesse porte di quella di destinazione (ospitano due servizi web nel mio caso ).


1

Ho sviluppato loco per aiutare con l'inoltro ssh. Può essere utilizzato per condividere le porte 5000 e 7000 in remoto localmente sulle stesse porte:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

1

Se desideri una soluzione semplice che venga eseguita in background e che sia facile da eliminare, utilizza un socket di controllo

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

1

Ecco una soluzione ispirata a quella di Yuval Atzmon.

Ha alcuni vantaggi rispetto alla soluzione iniziale:

  • prima crea un unico processo in background e non uno per porta
  • genera l'alias che ti permette di uccidere i tuoi tunnel
  • si lega solo a 127.0.0.1 che è un po 'più sicuro

Puoi usarlo come:

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

E infine ucciderli tutti con 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

Puoi usare questa funzione zsh (probabilmente funziona anche con bash) (Inseriscilo ~/.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[@]"
}

Esempi:

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.