ssh -L transfère plusieurs ports


129

J'utilise actuellement un tas de:

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

où IP est la cible d'une machine sécurisée et PORT représente les ports que je transfère.

C'est parce que j'utilise beaucoup d'applications auxquelles je ne peux pas accéder sans cette transmission. Après avoir effectué cela, je peux accéder via localhost:PORT.

Le problème principal est survenu maintenant que j'ai en fait 4 de ces ports que je dois transmettre.

Ma solution est d'ouvrir 4 shells et de rechercher constamment dans mon historique pour rechercher exactement quels ports doivent être transférés, etc., puis d'exécuter cette commande - un dans chaque shell (devoir remplir des mots de passe, etc.).

Si seulement je pouvais faire quelque chose comme:

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

alors cela aiderait déjà vraiment.

Existe-t-il un moyen de faciliter cette tâche?

Réponses:


195

L' -Loption peut être spécifiée plusieurs fois dans la même commande. Chaque fois avec différents ports.


20
Au début, je n'ai pas compris cette réponse. Donc poster un exemple ici au cas où quelqu'un souffrirait la même chose. L'auteur voulait dire "ssh -L port0: ip: port0 -L port1: ip: port1 ..."
Mong H. Ng

96

Exactement ce que NaN a répondu, vous spécifiez plusieurs arguments -L. Je le fais tout le temps. Voici un exemple de redirection multi-port:

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

Remarque : C'est la même chose que -L localhost:8822:REMOTE_IP_1:22si vous ne spécifiez pas localhost.

Maintenant, avec cela, vous pouvez maintenant (à partir d'un autre terminal) faire:

ssh localhost -p 8822

se connecter sur REMOTE_IP_1le port22

et pareillement

ssh localhost -p 9922

se connecter sur REMOTE_IP_2le port22

Bien sûr, rien ne vous empêche de l'envelopper dans un script ou de l'automatiser si vous avez de nombreux hôtes / ports différents à transférer et vers certains spécifiques.

J'espère que cela t'aides.


Excellent complément à la réponse de Nan. Merci.
AFP_555

1
Soyez prudent à ce sujet: "Remarque: Ceci est identique à -L localhost: 8822: REMOTE_IP_1: 22 si vous ne spécifiez pas localhost." Cela n'est vrai que si le paramètre GatewayPorts est «no», ce qui est certes la valeur par défaut. Mais compte tenu des implications si ce n'est pas le cas, vous devriez vérifier le paramètre ou, mieux encore, être explicite et utiliser "-L localhost: 8822 ...".
David

Je suis d'accord avec @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

Vous pouvez utiliser la fonction bash suivante (ajoutez-la simplement à votre ~/.bashrc):

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

Exemple d'utilisation:

pfwd hostname {6000..6009}

2
Utilisez -fpour courir en arrière
Karl Pokus

Ehmmm ... pourquoi voulez-vous le faire de cette façon?
Anton Bessonov le

14

Les personnes qui transfèrent plusieurs ports via le même hôte peuvent configurer quelque chose comme ça dans leur ~ / .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

et cela devient simple ssh all-port-forwards.


J'aime cette approche.
BMW le

8

jbchichoko et yuval ont donné des solutions viables. Mais la réponse de jbchichoko n'est pas une réponse flexible en tant que fonction, et les tunnels ouverts par la réponse de yuval ne peuvent pas être fermés ctrl+ccar ils fonctionnent en arrière-plan. Je donne ma solution ci-dessous en résolvant les deux défauts:

Définir une fonction dans ~/.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
}

Un exemple d'exécution de la fonction:

fsshmap 6000 6010 hostname

Résultat de cet exemple:

Vous pouvez accéder 127.0.0.1:16000~16009au même quehostname:6000~6009


3

L'un des avantages de la connexion à un serveur avec la redirection de port est de faciliter l'utilisation de Jupyter Notebook. Ce lien fournit une excellente description de la façon de procéder. Ici, je voudrais faire un résumé et une extension pour que vous puissiez tous vous référer.

Situation 1. Connectez-vous à partir d'une machine locale nommée Host-A (par exemple votre propre ordinateur portable) à une machine de travail distante nommée Host-B.

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

Ensuite, vous pouvez ouvrir un navigateur et entrer: http: // localhost: port_A / pour faire votre travail sur l'hôte-B mais le voir dans l'hôte-A.

Situation 2. Connectez-vous à partir d'une machine locale nommée Host-A (par exemple votre propre ordinateur portable) à une machine de connexion distante nommée Host-B et de là, connectez-vous à la machine de travail distante nommée Host-C. C'est généralement le cas pour la plupart des serveurs analytiques au sein des universités et peut être réalisé en utilisant deux ssh -Lconnectés avec -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

Ensuite, vous pouvez ouvrir un navigateur et entrer: http: // localhost: port_A / pour faire votre travail sur l'hôte-C mais le voir dans l'hôte-A.

Situation 3. Connectez-vous à partir d'une machine locale nommée Host-A (par exemple votre propre ordinateur portable) à une machine de connexion distante nommée Host-B et de là connectez-vous à la machine de travail distante nommée Host-C et enfin connectez-vous à la machine de travail distante Host- RÉ. Ce n'est généralement pas le cas, mais cela peut arriver parfois. C'est une extension de la situation 2 et la même logique peut être appliquée sur plus de machines.

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

Ensuite, vous pouvez ouvrir un navigateur et entrer: http: // localhost: port_A / pour faire votre travail sur l'hôte-D mais le voir dans l'hôte-A.

Notez que port_A, port_B, port_C, port_D peuvent être des nombres aléatoires à l'exception des numéros de port communs listés ici . Dans la situation 1, port_A et port_B peuvent être identiques pour simplifier la procédure.


Un rappel, même port sur différents serveurs sont des ports différents. Par conséquent, cela pourrait toujours faciliter les choses en spécifiant un numéro de port identique!
Fei Yao le

3

Dans mon entreprise, les membres de mon équipe et moi-même avons besoin d'accéder à 3 ports d'un serveur «cible» non accessible, j'ai donc créé un tunnel permanent (c'est-à-dire un tunnel qui peut fonctionner en arrière-plan indéfiniment, voir les paramètres -fet -N) depuis un serveur accessible vers la cible. Sur la ligne de commande du serveur accessible, j'ai exécuté:

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

J'ai utilisé l'utilisateur rootmais votre propre utilisateur fonctionnera. Vous devrez entrer le mot de passe de l'utilisateur choisi (même si vous êtes déjà connecté au serveur accessible avec cet utilisateur).

Maintenant le port 8822 de la machine joignable correspond au port 22 de la cible (pour ssh / PuTTY / WinSCP) et les ports 9006 et 9100 sur la machine joignable correspondent aux mêmes ports de la cible (ils hébergent deux services web dans mon cas ).


1

J'ai développé loco pour aider à la transmission ssh. Il peut être utilisé pour partager les ports 5000 et 7000 à distance localement sur les mêmes ports:

pip install loco

loco listen SSHINFO -r 5000 -r 7000

1

Si vous voulez une solution simple qui s'exécute en arrière-plan et est facile à tuer - utilisez une prise de contrôle

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

1

Voici une solution inspirée de celle de Yuval Atzmon.

Elle présente quelques avantages par rapport à la solution initiale:

  • d'abord, il crée un processus d'arrière-plan unique et non un par port
  • il génère l'alias qui vous permet de tuer vos tunnels
  • il se lie uniquement à 127.0.0.1 qui est un peu plus sécurisé

Vous pouvez l'utiliser comme:

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

Et enfin les tuer tous avec 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

Vous pouvez utiliser cette fonction zsh (fonctionne probablement aussi avec bash) (Mettez-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[@]"
}

Exemples:

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.