web-dev-qa-db-fra.com

Comment fonctionne le tunneling SSH inversé?

Si je comprends bien, les pare-feu (en supposant les paramètres par défaut) refusent tout le trafic entrant qui n'a pas de trafic sortant correspondant antérieur.

Basé sur Inverser une connexion ssh et SSH Tunneling Made Easy , le tunnel SSH inversé peut être utilisé pour contourner les restrictions de pare-feu embêtantes.

Je voudrais exécuter des commandes Shell sur une machine distante. La machine distante possède son propre pare-feu et se trouve derrière un pare-feu supplémentaire (routeur). Il a une adresse IP comme 192.168.1.126 (ou quelque chose de similaire). Je ne suis pas derrière un pare-feu et je connais l'adresse IP de la machine distante vue depuis Internet (pas l'adresse 192.168.1.126). De plus, je peux demander à quelqu'un d'exécuter ssh (something) en tant que root sur la machine distante en premier.

Quelqu'un pourrait-il m'expliquer, étape par étape, comment fonctionne le tunneling SSH inverse pour contourner les pare-feu (pare-feu des machines locales et distantes et le pare-feu supplémentaire entre eux)?

Quel est le rôle des commutateurs (-R, -f, -L, -N)?

376
Ali

J'adore expliquer ce genre de chose à travers la visualisation. :-)

Considérez vos connexions SSH comme des tubes. Gros tubes. Normalement, vous atteindrez ces tubes pour exécuter un shell sur un ordinateur distant. Le shell s'exécute dans un terminal virtuel (tty). Mais vous connaissez déjà cette partie.

Considérez votre tunnel comme un tube dans un tube. Vous avez toujours la grande connexion SSH, mais l'option -L ou -R vous permet de configurer un tube plus petit à l'intérieur.

Chaque tube a un début et une fin. Le gros tube, votre connexion SSH, a commencé avec votre client SSH et se termine sur le serveur SSH auquel vous vous êtes connecté. Tous les tubes plus petits ont les mêmes extrémités, sauf que le rôle de "début" ou "fin" est déterminé selon que vous avez utilisé -L Ou -R (Respectivement) pour les créer.

(Vous ne l'avez pas dit, mais je vais supposer que la machine "distante" que vous avez mentionnée, celle qui se trouve derrière le pare-feu, peut accéder à Internet à l'aide de la traduction d'adresses réseau (NAT). C'est assez important, donc veuillez corriger cette hypothèse si elle est fausse.)

Lorsque vous créez un tunnel, vous spécifiez une adresse et un port sur lesquels il répondra, ainsi qu'une adresse et un port sur lesquels il sera livré. L'option -L Indique au tunnel de répondre du côté local du tunnel (l'hôte exécutant votre client). L'option -R Indique au tunnel de répondre du côté distant (le serveur SSH).

ssh tunnel directions

Donc ... Pour pouvoir SSH depuis Internet vers une machine derrière un pare-feu, vous avez besoin de la machine en question pour ouvrir une connexion SSH vers le monde extérieur et inclure un tunnel -R Dont le point "d'entrée" est le côté "distant" de sa connexion.

Des deux modèles illustrés ci-dessus, vous voulez celui de droite.

Depuis l'hôte pare-feu:

ssh -f -N -T -R22222:localhost:22 yourpublichost.example.com

Ceci indique à votre client d'établir un tunnel avec un point d'entrée emote -R. Tout ce qui se connecte au port 22222 à l'extrémité du tunnel atteindra en fait le "port localhost 22", où "localhost" est du point de vue du point de sortie du tunnel (c'est-à-dire votre client ssh).

Les autres options sont:

  • -f Indique à ssh de se mettre en arrière-plan après s'être authentifié, vous n'avez donc pas à vous asseoir pour exécuter quelque chose sur le serveur distant pour que le tunnel reste en vie.
  • -N Indique que vous souhaitez une connexion SSH, mais que vous ne voulez en fait exécuter aucune commande à distance. Si tout ce que vous créez est un tunnel, l'inclusion de cette option permet d'économiser des ressources.
  • -T Désactive l'allocation de pseudo-tty, ce qui est approprié car vous n'essayez pas de créer un shell interactif.

Il y aura un défi de mot de passe sauf si vous avez configuré des clés DSA ou RSA pour une connexion sans mot de passe.

Notez qu'il est FORTEMENT recommandé d'utiliser un compte jetable (pas votre propre identifiant) que vous avez configuré uniquement pour ce tunnel/client/serveur.

Maintenant, à partir de votre shell sur yourpublichost , établissez une connexion à l'hôte pare-feu via le tunnel:

ssh -p 22222 username@localhost

Vous aurez un défi clé pour l'hôte, car vous n'avez probablement jamais rencontré cet hôte auparavant. Ensuite, vous obtiendrez un défi de mot de passe pour le compte username (sauf si vous avez configuré des clés pour une connexion sans mot de passe).

Si vous allez accéder régulièrement à cet hôte, vous pouvez également simplifier l'accès en ajoutant quelques lignes à votre fichier ~/.ssh/config:

Host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Ajustez remotehostname et remoteusername en fonction. Le champ remoteusername doit correspondre à votre nom d'utilisateur sur le serveur distant, mais remotehostname peut être n'importe quel nom d'hôte qui vous convient, il ne doit correspondre à rien de résolvable.

Voir également:

433
ghoti

J'ai dessiné quelques croquis

La machine sur laquelle la commande ssh tunnel est tapée s'appelle "votre hôte".

ssh tunnel starting from local


ssh tunnel starting from remote

Introduction

  1. local: -L Specifies that the given port on the local (client) Host is to be forwarded to the given Host and port on the remote side.

    ssh -L sourcePort:forwardToHost:onPort connectToHost Signifie: connectez-vous avec ssh à connectToHost, et transférez toutes les tentatives de connexion au localsourcePort au port onPort sur le machine appelée forwardToHost, accessible depuis la machine connectToHost.

  2. à distance: -R Specifies that the given port on the remote (server) Host is to be forwarded to the given Host and port on the local side.

    ssh -R sourcePort:forwardToHost:onPort connectToHost Signifie: connectez-vous avec ssh à connectToHost, et transférez toutes les tentatives de connexion à distantsourcePort au port onPort sur le machine appelée forwardToHost, accessible depuis votre machine locale.

Options additionelles

  • -f Indique à ssh de se mettre en arrière-plan après s'être authentifié, vous n'avez donc pas à vous asseoir pour exécuter quelque chose sur le serveur distant pour que le tunnel reste en vie.
  • -N Indique que vous souhaitez une connexion SSH, mais que vous ne voulez en fait exécuter aucune commande à distance. Si tout ce que vous créez est un tunnel, l'inclusion de cette option permet d'économiser des ressources.
  • -T Désactive l'allocation de pseudo-tty, ce qui est approprié car vous n'essayez pas de créer un shell interactif.

Votre exemple

La troisième image représente ce tunnel. Mais l'ordinateur bleu appelé "votre hôte" représente l'ordinateur où quelqu'un démarre le tunnel ssh, dans ce cas la machine pare-feu .

Alors, demandez à quelqu'un de démarrer une connexion tunnel ssh à votre machine. La commande devrait ressembler à

ssh -R 12345:localhost:22 YOURIP

Maintenant, le tunnel est ouvert. Vous pouvez maintenant vous connecter via ssh à la machine pare-feu via le tunnel avec la commande

ssh -p 12345 localhost

qui se connectera à votre propre localhost (votre machine) sur le port 12345, mais le port 12345 est transmis via le tunnel au port 22 de l'hôte local de l'ordinateur pare-feu (c'est-à-dire l'ordinateur pare-feu lui-même).

389
erik

la tunnellisation ssh fonctionne en utilisant la connexion ssh déjà établie pour envoyer du trafic supplémentaire.

Lorsque vous vous connectez à un serveur distant, vous n'avez généralement qu'un seul canal pour l'interaction utilisateur normale (ou 3 canaux si vous considérez STDIN/STDOUT/STDERR séparément). À tout moment, le processus ssh local ou distant peut ouvrir des canaux supplémentaires sur la connexion existante. Ces canaux envoient/reçoivent ensuite le trafic du tunnel. Lors de l'envoi ou de la réception de trafic, le processus ssh indique simplement "ce trafic est destiné au canal foobar".

Cela fonctionne essentiellement comme ceci:

  1. Vous dites à ssh de commencer l'écoute sur le port XXXX et que tout trafic reçu doit être tunnelisé, puis défini sur Y.Y.Y.Y sur le port ZZZZ.
  2. Le ssh local commence à écouter sur le port XXXX (généralement sur 127.0.0.1, mais peut être modifié).
  3. Certaines applications ouvrent une connexion au port XXXX sur la machine locale.
  4. Le ssh local ouvre un canal au ssh distant et dit "tout trafic sur ce canal va à Y.Y.Y.Y: ZZZZ
  5. Le ssh distant se connecte à Y.Y.Y.Y: ZZZZ et renvoie le message "OK, le canal est ouvert"
  6. Désormais, tout trafic envoyé le long de la connexion au port XXXX sur la machine locale est acheminé par ssh vers Y.Y.Y.Y: ZZZZ.

Ce processus est exactement le même pour la tunnellisation vers l'avant et vers l'arrière (il suffit d'échanger les mots "local" et "distant" dans la procédure ci-dessus). Chaque côté peut démarrer le tunnel. Il n'est même pas nécessaire que ce soit au premier démarrage de ssh. Vous pouvez ouvrir des tunnels pendant que ssh est déjà en cours d'exécution (voir ESCAPE CHARACTERS, Plus précisément ~C).

Pour le rôle de -R, -f, -L, et -N, vous devriez vraiment consulter la page de manuel, elle vous donne la meilleure explication possible. Mais je mentionnerai -R et -L.
-R indique au ssh distant d'écouter les connexions et que le ssh local doit se connecter à la destination réelle. -L indique au ssh local d'écouter les connexions et que le ssh distant doit se connecter à la destination réelle.

Remarque, ceci est une description très grossière, mais elle devrait vous donner suffisamment d'informations pour savoir ce qui se passe

24
Patrick

Ceci est expliqué dans le manuel SSH, en particulier les différences entre -L (local) et -R (à distance).


-L

-L [bind_address:]port:Host:hostport

Spécifie que le port donné sur l'hôte local (client) doit être transmis à l'hôte donné et au port distant .

Cela fonctionne en allouant un socket pour écouter le port du côté local, éventuellement lié à la bind_address spécifiée.

Chaque fois qu'une connexion est établie avec ce port, la connexion est transmise sur le canal sécurisé et une connexion est établie vers Host port hostport depuis la machine distante .

L'exemple suivant tunnels une session IRC depuis la machine cliente 127.0.0.1 (localhost) utilisant le port 1234 vers le serveur distant server.example.com:

$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10

Noter la -f arrière-plans de l'option ssh et la commande à distance sleep 10 est spécifié pour laisser un certain temps pour démarrer le service à tunnelliser.

Exemple:

ssh `-N` -L 22000:localhost:11000 remote.server.com
  • -N Une fois connecté, accrochez-vous (vous n'obtiendrez pas d'invite Shell)

    N'exécutez pas de commande à distance.

  • -L 22000 La connexion sera établie sur le port 22000 de votre ordinateur personnel [~ # ~] l [~ # ~]

  • localhost:11000 - remote.server.com s'assurera que l'autre extrémité du tunnel est localhost, port 11000

ssh -N -L 22000:192.168.1.2:11000 remote.server.com

Source: n guide illustré, tutoriel, how-to, sur ssh tunneling .


-R

-R [bind_address:]port:Host:hostport

Spécifie que le port donné sur l'hôte (serveur) distant doit être transmis à l'hôte et au port donnés du côté local .

Cela fonctionne en allouant un socket pour écouter port du côté distant, et chaque fois qu'une connexion est établie à ce port, la connexion est transférée sur le canal sécurisé, et une connexion est établie avec Host port hostport depuis la machine locale .

Exemple:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N Une fois connecté, accrochez-vous (vous n'obtiendrez pas d'invite Shell)

    N'exécutez pas de commande à distance.

  • -R 22000 La connexion sera établie sur le port 22000 de l'ordinateur émote [~ # ~] r [~ # ~] (dans ce cas, distant. server.com)

  • localhost:11000 votre ordinateur personnel local s'assurera que l'autre extrémité du tunnel est localhost, port 11000

ssh -N -R 22000:localhost:11000 remote.server.com

Source: n guide illustré, tutoriel, how-to, sur ssh tunneling .

18
kenorb