Tunnel SSH local et renverse

28/01/2008

J’ai déjà traité ce sujet il y a quelques temps, mais je n’avais pas bien approfondi les différentes options et alternatives qui peuvent exister pour créer un tunnel SSH. J’avais simplement oublié de parler des tunnels inversés (reverse tunneling) et il manquait d’exemples. Voilà qui est corrigé dans ce qui va suivre.

qu’est-ce que SSH

SSH est un shell sécurisé. Il remplace presque unanimement telnet, et a l’avantage d’être très solide en terme de sécurité. Il sait géré des connexions avec des paires de clefs dont l’algorithme de cryptage peut être réglé (DSA, RSA, etc…)

SSH est un protocole, son implémentation dans OpenSSH est la plus répandue à ce jour. Toutes les distributions Linux ont OpenSSH installé, et ce pour notre plus grand plaisir. Il nous permet de nous connecter à distance sur des machines ayant un service SSH ouvert, laissant aux administrateurs de serveurs une possibilité de gestion en mode console très facile.

Au dessus de SSH se supplante SFTP (Secured File Transfert Protocol). Un protocole SSH très répandu, utilisant SSH pour le transport. Il permet, à l’instar de FTP, de faire transiter des fichiers mais avec une sécurité de connexion accrue.

Ce qu’est un tunnel

Un tunnel est un passage ouvert entre deux machines distantes. Ce passage sera emprunté par des “paquets” provenant de clients.

En fait, pour faire simple, une machine A va écouter sur un port, et faire transiter tout ce qui arrive sur ce port vers une autre machine B. Le transit entre A et B est un tunnel.

L’idée est “d’imiter” un “port forwarding”, comprenez une “redirection de port”.

Le rapport avec SSH ?

SSH n’est pas qu’un simple outil de connexion de SHELL. Il offre tout un panel de possibilité de connexion diverses. Outre SFTP, comme nous l’avons vu plus haut, il permet de créer des tunnels offrant en plus de cela son cryptage de données.

A quoi cela va me servir, concrétement ?

Il est vrai que les tunnels ne sont pas des options dont on se sert tous les jorus, et pourtant il permet bien des fois de ne pas se casser la tête pour certaines problématiques.

Voici deux exemples: -Ma copine, en Angleterre, me demande un coup de main pour réparer quelque chose sur son ordinateur. Elle se trouve derrière un firewall, un routeur. Donc je ne peux pas me connecter à son poste directement. -Au travail, les machines des secrétaires n’ont pas accès au net, mais pendant quelques temps, j’ai besoin qu’elles puissent se connecter au serveur “foo.bar.com”, sur un port spécial (le 55200) et seul mon poste peut y accéder. -J’ai simplement envie de me connecter à mon pc qui est à la maison, depuis mon poste au travail… et ce sans avoir à paramétrer ma LiveBox pour faire un forward vers le port 22 de ma machine… surtout que c’est juste pour un temps… -Mon serveur Apache est planté… je veux redirriger mes clients sur un autre serveur le temps que je puisse redémarrer Apache -… etc

Bref, dans tous les cas, il faut pouvoir redirriger des flux d’un endroit vers un autre. Et là, les tunnels vont se construire plus vite et plus simplement qu’il n’y parait !

Tunnel local et tunnel inversé ?

Il existe deux type de tunnels: l’un en local, l’autre en “reverse”. Pour savoir lequel utiliser, il faut se poser une seule question: \ __qui va écouter les données et rediriger le tout ?__ Si vous avez la réponse:

-Cas 1: C’est mon poste qui va écouter et je renvois tout à un serveur pour rediriger: mode local -Cas 2: c’est une machine distante qui doit écouter, et c’est mon poste qui gère les redirections: reverse

Attention tout de même: le serveur et votre poste peuvent être la même machine. Il faut bien identifier l’écouteur et le receveur.

Voyons les deux méthodes, et vous pourrez faire votre choix après.

Mode local, Listen (-L)

Dans ce mode, votre machine va écouter un port, et rediriger les paquets sur un serveur qui s’occupera de dispatcher les requêtes sur la cible spécifier.

ssh -N -L portlocal:www.example.com:80 user@foo.org

On décrypte la commande: -ssh -N se mettra en attente après lancement de la commande ssh --L on va écouter en local -portlocal : le port de notre PC qui va écouter -www.exemple.com:80 la cible qui sera pointé par: -foo.org -user: utilisateur de foo.org qui DOIT exister

  • - Important: la machine qui résoud le nom www.example.com est foo.org, autrement dit si vous utilisez “localhost” à la place de “www.exemple.com”, alors locahost vaut “foo.org”**

Exemple:\ Si vous avez un serveur distant, tentez de faire cela:

ssh -N -L 55962:www.metal3d.org:80 user@votre-server.com

Où “user” est un utilisateur connu de “votre-serveur.com” Vou venez de demande à votre PC d’écouter sur le port 55962. Toutes les demandes sur ce port iront sur “votre-server.com” qui les redirigera vers www.metal3d.org:80

Note: vous pouvez utiliser localhost à la place de votre-server.com

Dans FireFox, allez sur http://localhost:55962 et vous allez voir http://www.metal3d.org apparaitre.

Le principe est simple, mais permet de très grandes possibilités. Imaginez que vous ne puissiez pas passer par le port 21 pour aller sur votre FTP. Par contre vous pouvez passer par le port 22 (ssh). Et bien faites cela pour utiliser “votre-server” qui, lui, a le droit d’aller sur port 21 de n’importe qui:

ssh -N -L 55987:ftp.quevousvoulez.com:21 user@votre-server.com

en admettant que vous ayez un serveur distant évidemment. En connectant votre client FTP à localhost:55987, vous serez connecté à ftp.quevousvoulez.com au travers d’un tunnel entre vous et votre-server.com via le port 22.

Voyons maintenant le tunnel inversé, mode reverse, qui va permettre non plus de vous connecter vers un serveur distant, mais de rapatrier les paquets depuis un serveur distant… compliqué mon explication ? voyons un exemple.

Tunnel inversé, reverse (-R)

Mon PC à la maison est derrière une LiveBox. Autrement dit, un routeur. Je n’ai pas envie de tripatouiller mon routeur… Vous saurez que mon PC a donc une adresse “privé” (192.168.1.11) qui n’est pas accessible depuis internet. Seul mon routeur, qui change régulièrement d’ip, est acessible. C’est d’ailleurs son rôle.

Mais alors, comment, sans configurer le firewall, je peux accepter une connexion depuis un autre poste sur mon PC à la maison. La réponse est un tunnel inversé. Mon PC va demander à mon serveur d’écouter un port, et de lui renvoyer tout ça sur le port ssh (22).

ssh -N -R 21547:localhost:22 user@mon-serveur.org
  • - Important: La machine qui résoud “localhost” est votre machine autrement dit “localhost” est la machine sur laquelle vous tapez la commande **

Etant donné que je suis en mode inversé, “localhost” est résolu non plus par mon serveur, mais par mon PC.

Donc, depuis le travail, je me connecte sur “metal3d@mon-serveur.org -p 21547” et je me retrouve sur mon PC, à la maison. Le serveur écoute sur le port 21547 et redirige tout dans le tunnel.

On peut aussi faire en sorte de rediriger les données plus loin… par exemple:\ Je veux que mon serveur “mon-serveur” écoute sur le port 45678 et me renvois les connexion sur mon pc à la maison. Mon PC va ensuite les rediriger vers mon PC portable (seulement accessible dans mon réseau à la maison):

ssh -N -R 21547:pcportable:22 user@mon-serveur.org

De ce fait, depuis le travail, je tape:

ssh user@mon-serveur.org -p21547

et je suis connecté à mon portable. **Attention, user correspond à un utilisateur qui existe non pas sur le serveur, mais sur le pc portable**

Il m’a servit aussi à ça

Mise en attente, ne quittez pas

Lorsque mon serveur Apache a laché misérablement à cause d’un fichier de log trop gros, j’ai put mettre en attente mes clients: J’ai créé un fichier index.html avec un beau message d’attente “Désolé je suis planté un moment, revenez dans quelques minutes” sur mon PC personnel qui a Apache.

Ensuite, j’ai simplement tapé, sur mon pc à la maison:

ssh -N -R 80:localhost:80 root@www.metal3d.org

Il a fallut que je sois “root” pour ouvrir un port “réservé”. De là, toutes les personnes qui se connectaient sur mon serveur via le port 80 (http) étaient redirigés sur mon poste à la maison qui leur desservait une page d’attente. Après avoir résolu mon soucis, j’ai coupé la commande sur mon poste à la maison, et j’ai relancé Apache sur metal3d.org.

Passons le firewall

Au travail, 6 postes devaient se connecter à une plateforme téléphonique distante, sur un port très spécifique: 68233

Or, le firewall que je ne gérais pas à ce moment là nous bloquait tout sauf au proxy dont j’étais l’administrateur. L’attente d’une ouverture de port de la part du service (externe) qui gérait le firewall était trop longue, il fallait une solution d’attente qui permettrait de travailler pendant ce temps.

Sur le proxy, j’ai fait cela:

ssh -N -L -f 68233:server-telephonique:68233 root@localhost

//l’option -f permet de relacher la console après que la connexion soit ouverte, cela me permettait de fermet la console sans couper la connexion. Pour fermer le tunnel, il suffisait de chercher avec ps ax | grep ssh le “pid” de la commande, et de la killer simplement //

Puis nous avons configuré les postes clients pour se connecter au proxy plutôt qu’au serveur téléphonique.

Pendant presque un mois, le serveur a tourné, puis le firewall a été configuré pour laisser ouvert le port à nos postes clients. Facile !

Service interne

Un petit dernier pour la route. Cette fois, le site que je gérais devais se connecter à une base interne pour un service spécial. Le client externe devait faire une requête sur un serveur que nous avions dans nos locaux, or le seul point d’accès était en DMZ… le site web.

Et encore une fois, pas question d’ouvrir le port au clients, et (heureusement) le seul port ouvert entre la DMZ et nos locaux est: SSH (port 22) le reste ayant été jugé trop “dangereux”.

Donc, le serveur WEB peut se connecter à INTRA en ssh. INTRA étant dans nos locaux, il peut envoyer les demandes sur le serveur DB. Il a fallut demandé à WEB d’écouter un port et de tout renvoyer vers DB au travers de INTRA… vous suivez ?

       connexion                tunnel                 forward
CLIENT --------- >45123:WEB | -------- > 22:INTRA ---------- > 1521:DB
                            |
                         firewall

#en ssh, sur le serveur WEB:
ssh -N -L -f 45123:DB:1521 root@INTRA

Désormais, toutes les requêtes sur WEB:45123 partaient vers DB:1521 au travers d’un tunnel sur INTRA.

Bilan

Les possibilités sont immenses, si vous comprennez bien le principe et que j’ai été clair, vous aurez compris comment créer un tunnel et dans quel cas utiliser un forward local ou inversé.

Pour ma part, je me dis simple que: -si la machine que je veux atteindre est cachée par un firewall, j’utilise un reverse

Retenez cela: --R sert essentiellement à laisser des gens entrer chez vous: le serveur c’est vous --L sert essentiellement à rediriger les gens à l’exterieur

Ça peut vous intéresser aussi


Pont réseau et tunnel pour VirtualBox

J’utilise depuis peu VirtualBox, cela me permet de créer ...


Monter un répertoir ssh sans coupure

Je travaille souvent sur mon serveur (Linux évidemment) et j’...


OpenOffice en mode serveur

Il est parfois compliqué de créer des documents dignes de ...


OpenSSH et les socket de contrôle

Garder une connexion SSH active en arrière plan et pouvoir ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Xav - 30/01/2009

Bonjour, J’ai un serveur Windows avec sshd (Cygwin) dans une DMZ avec 2 LAN: @IP1 qu peut être atteinte de l’extérieur via un FW (port 22 ouvert) et une @IP2 sur un LAN cul-de-sac, sur laquelle tourne mon serveur RDP (port 3389). Comment puis-je me connecter depuis un PC extérieur à la DMZ sur mon serveur RDP ? A priori, un tunnel ssh devrait faire l’affaire, mais impossible de le configurer correctement… Merci pour votre aide. Xavier.

Metal3d - 02/02/2009

Salut, Deux méthodes pour ton cas:

Solution 1: Sur le cygwin: ssh -N -L 55555:IP2:3389 root@localhost

Et depuis l’extérieur tu te connectes sur le serveur en RDP sur le port 55555 de la machine IP1.

Solution 2 (préférable): Depuis ton poste en extérieur tu fais:

ssh -N -L 55555:IP2:3389 root@IP1

Dans ce cas, tu te connecte en RDP sur ta propre machine (localhost:3389). Cette solution est encore plus sécurisée puisque ton flux RDP passera par le tunnel SSH au travers du net.

Jean-Louis - 02/10/2012

De mon lycée (réseau, poste sous windows) je parviens bien, grâce à Putty, à me connecter à mon ordinateur distant (Linux) Je ne comprends pas comment créer un tunnel depuis le lycée pour pourvoir enter dans une machine du lycée depuis chez moi. Merci pour le conseil.

JL

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.