Comment fonctionne le tunneling SSH inverse?

350

Si j'ai bien compris, les pare-feu (en supposant les paramètres par défaut) interdisent tout trafic entrant sans trafic sortant correspondant.

Basé sur l' inversion d'une connexion SSH et le tunneling SSH Made Easy , le tunneling SSH inversé peut être utilisé pour contourner les restrictions de pare-feu gênantes.

Je voudrais exécuter des commandes shell sur une machine distante. La machine distante dispose 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 telle qu'elle est vue depuis Internet (pas l'adresse 192.168.1.126). De plus, je peux d'abord demander à quelqu'un de s'exécuter en ssh (something)tant que root sur la machine distante.

Quelqu'un pourrait-il m'expliquer, étape par étape, comment fonctionne le tunnel SSH inversé pour contourner les pare-feu (les pare-feu des machines locales et distantes et le pare-feu supplémentaire qui les sépare)?

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

Ali
la source

Réponses:

403

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

Pensez à vos connexions SSH en tant que tubes. Gros tubes. Normalement, à travers ces tubes, vous exécuterez un shell sur un ordinateur distant. Le shell s'exécute dans un terminal virtuel (tty). Mais vous connaissez déjà cette partie.

Pensez à 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 grand tube, votre connexion SSH, a commencé avec votre client SSH et se termine sur le serveur SSH auquel vous êtes connecté. Tous les tubes plus petits ont les mêmes extrémités, sauf que le rôle de "début" ou de "fin" est déterminé par leur utilisation -Lou -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 derrière le pare-feu, peut accéder à Internet à l'aide de la traduction d'adresses réseau (NAT). C'est assez important, alors 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 va répondre, ainsi qu'une adresse et un port sur lesquels il sera livré. L' -Loption indique au tunnel de répondre du côté local du tunnel (l'hôte exécutant votre client). L' -Roption indique au tunnel de répondre du côté distant (le serveur SSH).

ssh tunnel directions

Donc ... Pour pouvoir passer de SSH à partir d’Internet dans une machine derrière un pare-feu, vous avez besoin que la machine en question ouvre une connexion SSH au monde extérieur et inclue un -Rtunnel dont le point "entrée" est le côté "distant" de sa connexion.

Parmi les deux modèles présentés ci-dessus, vous voulez celui de droite.

Depuis l'hôte avec pare-feu:

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

Cela indique à votre client d'établir un tunnel avec un -Rpoint d'entrée emote. Tout ce qui se connecte au port 22222 situé à l'extrémité distante du tunnel atteindra en réalité "le port localhost 22", où "localhost" se situe du point de vue du point de sortie du tunnel (votre client ssh).

Les autres options sont:

  • -f indique à ssh de se fonder après son authentification pour ne pas avoir à exécuter quelque chose sur le serveur distant pour que le tunnel reste en vie.
  • -Nindique que vous voulez une connexion SSH, mais que vous ne voulez pas exécuter de commandes à 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 à moins que vous n'ayez 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 (et non votre propre identifiant) que vous avez configuré pour ce tunnel / client / serveur uniquement.

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

ssh -p 22222 username@localhost

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

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

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Ajustez remotehostnameet remoteusernameen fonction. Le remoteusernamechamp doit correspondre à votre nom d'utilisateur sur le serveur distant, mais remotehostnamepeut être n'importe quel nom d'hôte qui vous convient, il ne doit correspondre à rien qui puisse être résolu.

(Pour exposer le point de terminaison inversé sur une adresse IP autre que l' hôte local , consultez ce post )

Ghoti
la source
2
Qu'en est-il de SSH -D. S'il vous plaît expliquer en utilisant la même méthode.
BigSack
6
Les procurations SOCKS ne sont pas identiques aux tunnels. Si vous avez une question sur leur utilisation, posez-la .
Ghoti
12
J'ai du mal à suivre cette explication en raison de la faible utilisation des termes: serveur, client, machine locale, machine distante, hôte, yourpublichost, localhost, remotehostname. Avec tous ces termes vagues et indéfinis, on pourrait supposer que quelqu'un aurait besoin de 8 ordinateurs au maximum pour le configurer. Je le dis parce que dans tous les autres aspects, cela semble une très bonne explication. S'il vous plaît réduire et définir les termes.
Rucent88
4
@ Rucent88, je ne sais pas quelle réduction serait possible. Un client établit une connexion à un serveur. C'est la terminologie commune à travers le monde des réseaux. Les machines locales et distantes semblent assez évidentes. Si vous avez du mal à comprendre SSH ou la terminologie unix générale après avoir lu la documentation, je suis certain que vous n'aurez aucun mal à trouver des gens ici qui voudront bien répondre à vos questions.
Ghoti
9
@ ghoti C'est en effet déroutant, car les machines locales et distantes sont relatives. Lorsque je suis assis sur mon lieu de travail, mon ordinateur à la maison est la télécommande. Lorsque je suis assis à la maison, cet ordinateur est à distance. Le serveur et le client sont également source de confusion quand on parle de tunneling. Par exemple, si je me connecte chez moi après le travail avec ssh -R. Je me connecte à mon travail à partir de l'ordinateur à la maison en connectant localhost. Donc, du point de vue des sockets, le serveur est l’ordinateur domestique lui-même. Mais logiquement je me suis connecté à mon ordinateur de travail. C'est déroutant.
Calmarius
356

J'ai dessiné des croquis

La machine sur laquelle est saisie la commande ssh tunnel s'appelle «votre hôte» .

tunnel ssh à partir de local


tunnel ssh à partir de distant

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 connectToHostsignifie: se connecter avec ssh à connectToHost, et transférer toutes les tentatives de connexion au port local sourcePort pour mettre en communication onPortsur la machine appelée forwardToHost, accessible depuis la connectToHostmachine.

  2. éloigné: -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 connectToHostsignifie: se connecter avec ssh à connectToHost, et transférer toutes les tentatives de connexion à distance sourcePort vers le port onPortde la machine appelée forwardToHost, accessible depuis votre machine locale.

Options additionelles

  • -f indique à ssh de se fonder après son authentification pour ne pas avoir à exécuter quelque chose sur le serveur distant pour que le tunnel reste en vie.
  • -Nindique que vous voulez une connexion SSH, mais que vous ne voulez pas exécuter de commandes à 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 sur lequel quelqu'un démarre le tunnel ssh, dans ce cas, la machine protégée par un pare-feu.

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

ssh -R 12345:localhost:22 YOURIP

Maintenant le tunnel est ouvert. Vous pouvez maintenant vous connecter via ssh à la machine avec 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 12345est transféré par le tunnel au port 22 de l'hôte local de l'ordinateur protégé par un pare-feu (c'est-à-dire l'ordinateur protégé par un pare-feu lui-même).

erik
la source
9
Très bonne réponse! Utilisera cela dans une présentation.
Isaiah Turner
4
Je vous remercie. Je vous en prie. Si vous voulez les images vectorielles (svg ou pdf) écrivez-moi un message.
erik
1
@erik, comment avez-vous dessiné ces images?
Pacerier
31
Oh mec, j'aimerais que les pages de manuel puissent avoir des explications comme celle-ci! Merci!
Lucas Pottersky
30
Vous savez quoi ? Je n'ai même pas eu à lire l'explication textuelle. Bon travail !
deppfx
21

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

Lorsque vous vous connectez à un serveur distant, vous ne disposez généralement que d'un canal pour l'interaction utilisateur normale (ou de 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 le trafic de tunnel. Lors de l’envoi ou de la réception de trafic, le processus ssh indique simplement "ce trafic est destiné à la chaîne foobar".

Cela fonctionne essentiellement comme ceci:

  1. Vous dites à ssh de commencer à écouter sur le port XXXX et que tout le trafic reçu doit être tunnellisé, puis défini sur AAAA sur le port ZZZZ.
  2. Le ssh local commence à écouter sur le port XXXX (généralement activé 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 vers le ssh distant et dit "tout trafic sur ce canal va à YYYY: ZZZZ
  5. Le ssh distant se connecte à YYYY: ZZZZ et renvoie le message "OK, le canal est ouvert"
  6. Maintenant, tout trafic envoyé via la connexion au port XXXX sur la machine locale est envoyé par ssh à YYYY: ZZZZ.

Ce processus est exactement le même pour les tunnels aller et retour (il suffit d’échanger les mots «local» et «distant» dans la procédure ci-dessus). Les deux côtés peuvent démarrer le tunnel. Il n'est même pas nécessaire que ce soit lorsque vous démarrez ssh. Vous pouvez ouvrir des tunnels alors que ssh est déjà en cours d'exécution (voir plus ESCAPE CHARACTERSprécisément ~C).

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

Notez que ceci est une description très grossière, mais elle devrait vous donner assez d’informations pour savoir ce qui se passe.

Patrick
la source
16

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


-L

-L [bind_address:]port:host:hostport

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

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

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 sur un hostport à hostportpartir de la machine distante .

L'exemple suivant tunnelise une session IRC depuis un ordinateur client 127.0.0.1( localhost) utilisant le port 1234 vers un serveur distant server.example.com:

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

Remarque: L' -foption backgrounds ssh et la commande remote sleep 10sont spécifiés 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 ne recevrez pas d’invite du shell)

    N'exécutez pas de commande à distance.

  • -L 22000La connexion proviendra sur le port 22000 de votre, personnel L machine Ocal

  • localhost:11000- remote.server.comfera en sorte que l'autre extrémité du tunnel est localhost, le port11000

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

Source: Un guide illustré, tutoriel, tutoriel, sur la tunnelisation SSH .


-R

-R [bind_address:]port:host:hostport

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

Cela fonctionne en allouant un socket pour écouter portcô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 sur un hostport à hostportpartir de la machine locale .

Exemple:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N Une fois connecté, accrochez-vous (vous ne recevrez pas d’invite du shell)

    N'exécutez pas de commande à distance.

  • -R22000 La connexion sera établie sur le port 22000 de l' ordinateur R emote (dans ce cas, remote.server.com).

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

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

Source: Un guide illustré, tutoriel, tutoriel, sur la tunnelisation SSH .

Kenorb
la source
6
l'oreille et la bouche indiquent clairement qui parle et qui écoute!
Thufir
1
J'adore tes illustrations!
mcantsin