42 votes

Accès SSH à l'hôte du bureau derrière un routeur NAT

Je voudrais accéder au port ssh de mon hôte linux de bureau depuis chez moi. Malheureusement, l'hôte est situé derrière un routeur NAT. Ainsi, l'adresse IP n'est pas publiquement disponible. Cependant, il y a accès à un autre hôte internet (Serveur) qui malheureusement n'a que des accès non-root. Après un certain temps de recherche, je ne trouve pas de solution adaptée.

Configuration suivante:

  • PC de bureau (linux, accès root) derrière NAT (IP non publique) mais accès Internet complet.
  • PC Serveur (linux, sans accès root) IP statique et publique et accès Internet complet.
  • PC personnel (linux, accès root) derrière NAT (IP non publique) mais accès Internet complet.

Connexions possibles: PC de bureau --> Serveur <-- PC personnel

Non possible: PC de bureau <-X- Serveur -X-> PC personnel

Le PC personnel et le Serveur ne peuvent pas initier l'accès au PC de bureau. Mais le PC de bureau et le PC personnel peuvent tous deux initier des connexions vers le Serveur.

Tunnel SSH inversé pas possible: J'ai essayé une méthode appelée tunnel ssh inversé. Malheureusement, cela nécessite que GatewayPorts sur le Serveur soit défini sur "yes" dans /etc/ssh/sshd_config, où je n'ai pas accès root.

En principe, cela devrait être possible:

0) Sur le Serveur, je lance un programme utilisateur qui écoute sur 2 ports (1 entrant, 1 sortant)

1) Sur mon PC de bureau, je lance un autre programme qui maintient une connexion TCP ouverte vers le port sortant du serveur.

2) Depuis chez moi, je me connecte au port entrant du Serveur.

Il devrait y avoir une solution standard pour cela quelque part.

Quelle est la solution la plus rapide et la plus propre pour résoudre cela?

Frank

39voto

Mike Schall Points 241
youatwork@officepc$ autossh -R 12345:localhost:22 notroot@serverpc

Plus tard :

you@homepc$ autossh -L 23456:localhost:12345 notroot@serverpc

you@homepc$ ssh youatwork@localhost -p 23456

Ce que vous pouvez faire est le suivant : à l'étape 1, faites avancer un port distant à partir du PC de bureau vers le serveur (12345 est utilisé à titre d'exemple, n'importe quel port >1024 fera l'affaire). Maintenant, en vous connectant au port 12345 sur le serveur, vous devriez vous connecter au port 22 sur officepc.

À l'étape 2, faites avancer le port 23456 de votre machine à domicile vers 12345 sur le serveur (d'où il est transmis à officepc:22, comme configuré à l'étape 1)

À l'étape 3, vous vous connectez au port local 23456 avec votre connexion au PC de bureau. Cela est transmis par l'étape 2 au port 12345 sur votre serveur, puis par l'étape 1 à votre PC de bureau.

Remarquez que j'utilise autossh pour les transferts, car c'est un wrapper ssh qui reconnecte automatiquement le tunnel en cas de déconnexion ; cependant, ssh normal fonctionnerait aussi, tant que la connexion ne se coupe pas.

Il existe une vulnérabilité potentielle : quiconque peut se connecter à localhost:12345 sur serverpc peut maintenant se connecter à officepc:22 et essayer de s'y introduire. (Remarquez que si vous exécutez un serveur SSH, vous devriez de toute façon le sécuriser au-dessus des protections de base qui sont activées par défaut ; je recommande au moins de désactiver la connexion root et de désactiver l'authentification par mot de passe - voir par exemple ceci)

Édition : J'ai vérifié cela avec la même configuration, et cela fonctionne. GatewayPorts no n'affecte que les ports ouverts au monde entier, pas les tunnels locaux. Voici les ports transférés :

homepc :
  sortie ssh vers serverpc:22
  écoute localhost:23456 transmise à travers le tunnel ssh
serverpc :
  écoute ssh à *:22
  tunnel ssh entrant localhost (de homepc) transmis à localhost:12345
  tunnel ssh local entrant (de officepc) transmis de localhost:12345
officepc :
  sortie ssh vers serverpc:22
  tunnel entrant localhost via ssh (de serverpc) transmis à localhost:22

Ainsi, du point de vue de la pile réseau, il s'agit de trafic local sur les interfaces de bouclage respectives (plus les connexions ssh vers serverpc) ; par conséquent, GatewayPorts n'est pas du tout vérifié.

Cependant, il existe la directive AllowTcpForwarding : si celle-ci est no, cette configuration échouera car aucun transfert n'est autorisé du tout, même à travers l'interface de bouclage.

Avertissements :

  • si vous utilisez autossh et un ssh récent, vous voudrez peut-être utiliser ServerAliveInterval et ServerAliveCountMax de ssh pour maintenir le tunnel actif. Autossh a une vérification intégrée, mais apparemment elle a des problèmes sur Fedora. -M0 la désactive, et -oServerAliveInterval=20 -oServerAliveCountMax=3 vérifie si la connexion est active - essaie toutes les 20 secondes, si elle échoue 3 fois de suite, arrête ssh (et autossh en crée un nouveau) :

    autossh -M0 -R 12345:localhost:22 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc
    
    autossh -M0 -L 23456:localhost:12345 -oServerAliveInterval=20 -oServerAliveCountMax=3 notroot@serverpc
  • il peut être utile de redémarrer le tunnel SSH si le transfert échoue, en utilisant -oExitOnForwardFailure=yes - si le port est déjà lié, vous pourriez obtenir une connexion SSH fonctionnelle, mais aucun tunnel transmis.

  • l'utilisation de ~/.ssh/config pour les options (et ports) est conseillée, sinon les lignes de commande deviennent trop verbeuses. Par exemple :

    Hôte fwdserverpc
        Nom d'hôte serverpc
        Utilisateur notroot
        ServerAliveInterval 20
        ServerAliveCountMax 3
        ExitOnForwardFailure yes
        LocalForward 23456 localhost:12345

Ensuite, vous pouvez utiliser simplement l'alias du serveur :

    autossh -M0 fwdserverpc

4voto

Michael Points 461

Si vous pouvez vous connecter en ssh au serveur interne depuis chez vous et depuis le serveur interne à votre machine Linux de bureau, alors depuis chez vous vous pouvez utiliser la commande ProxyCommand ssh pour rebondir silencieusement à travers le serveur vers la machine interne via nc (netcat)

# ~/.ssh/config sur votre machine de chez vous :
Host internalpc 
   ForwardAgent yes 
   ProxyCommand ssh user@server.example.com exec nc internal.pc.example.com %p

Ensuite vous n'avez qu'à faire ssh user@internalpc et vous êtes renvoyé silencieusement à travers le serveur, sans avoir besoin d'ouvrir des ports ou des tunnels des deux côtés.

4voto

Installez Robo-TiTO sur l'ordinateur auquel vous souhaitez accéder en SSH à distance.

  • Cela vous permettra d'accéder en SSH à partir de n'importe où en utilisant les applications Google Talk Client.
  • Il n'est pas nécessaire d'avoir une adresse IP publique ou des paramètres spéciaux.
  • C'est gratuit et open source, ne payez plus aucun service d'application.
  • Il n'est pas nécessaire d'ouvrir le port SSH (gardez votre ordinateur en sécurité).
  • Il n'est pas nécessaire d'ouvrir un tunnel (par exemple, VPN ou quelque chose du genre)

Les instructions d'installation suivantes sont obsolètes, car le site a déménagé. La nouvelle URL est https://github.com/formigarafa/robotito

~~J'ai créé un script (testé sur mon OS Raspbian sur Raspberry Pi) pour vous permettre d'installer facilement Robo-TiTO sur Raspberry Pi, Debian ou Ubuntu Box (distribution de paquets Debian). Voici les étapes pour rendre votre boîte Linux accessible à distance :

  1. Ouvrez un Terminal ou invite de commande Shell, allez dans votre dossier personnel, téléchargez le script d'installation avec la commande :

    $ wget https://opengateway.googlecode.com/files/robotito
  2. ensuite exécutez le script en entrant la commande :

    $ sudo ./robotito
  3. et ensuite vous pouvez éditer le fichier credentials.rb du dossier de configuration de Robo-TiTO en utilisant votre compte GTalk et enregistrez-le en appuyant sur Ctrl+X puis Y.  L'éditeur par défaut est nano.

  4. démarrer Robo-TiTO depuis le dossier Robo-TiTO en utilisant la commande

    $ cd robotito
    $ ./jabbershd start
  5. Maintenant que c'est fait, vous pouvez utiliser SSH à partir de n'importe quel client Google talk. N'oubliez pas d'ajouter le compte GTalk Robo-TiTO à votre compte Google talk et de le tester en discutant avant d'utiliser le compte.

~~

3voto

Kristian Points 71

La solution de Piskvor fonctionne et est agréable. Cependant, elle laisse des terminaux ouverts avec des shells de connexion en suspension. Pas très cool.

J'ai toujours utilisé ce petit script que j'ai écrit pour me connecter à un serveur et le maintenir connecté en le lançant dans cron :

#!/bin/bash
TARGET_HOST=${1:-monserveur.example.com}
TARGET_PORT=${2:-7777}
TUNNEL_PORT=${3:-22}
T_USER="odin"

# Vérifier que nous avons une connexion active vers le système distant
ACTIVE_PROCESS=`ps -ef | \
    grep "ssh $TARGET_HOST -l $T_USER -R $TARGET_PORT:127.0.0.1:$TUNNEL_PORT" | \
    grep -v grep | \
    wc -l`
if [ $ACTIVE_PROCESS -lt 1 ]; then
    echo "`date` : establishing connection to $TARGET_HOST on port $TARGET_PORT"
    screen -m -d ssh $TARGET_HOST -l $T_USER -R $TARGET_PORT:127.0.0.1:$TUNNEL_PORT > /dev/null
fi

Je parie que nous pourrions corriger la solution de Piskvor en utilisant l'outil plus élégant autossh avec peut-être un écran détaché ou en utilisant les arguments -NT ssh pour simplement maintenir la connexion en arrière-plan.

2voto

djangofan Points 2677

Pour moi, cela ressemble plutôt à un VPN qu'à un tunnel SSH : un VPN qui fonctionne en utilisant un serveur à l'extérieur pour se connecter en proxy, comme Hamachi. Il y a d'autres logiciels gratuits comme celui-ci, mais Hamachi est mon préféré.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X