Journal Tunneling SSH conteneurisé

Posté par  . Licence CC By‑SA.
Étiquettes :
8
4
jan.
2020

Sommaire

Cher journal,

j'aimerais te présenter un petit projet pour monter très facilement ton propre tunnel SSH à la maison, comme un grand: https://github.com/second-reality/reverse-tunnel

Pour résumer, cela permet de faire transiter un trafic donné via ssh. Cela offre différentes possibilités:
- utiliser un protocole non sécurisé (comme ftp) sur un réseau ouvert, en passant via une machine relai, sans risque d'interception.
- accéder à une machine non disponible publiquement sur le net, via une machine relai (publique).
- crée un ersatz de VPN pour accéder à des données bloquées dans ton pays (si tu disposes d'un serveur à l'étranger).
- et bien d'autres choses…

Le cas qui m'intéresse, c'est le deuxième. À savoir, accéder à la machine du boulot depuis chez moi, facilement.

Voici un résumé bien plus complet: https://wiki.korben.info/Tunnel_SSH


Exemples

Accès à une machine derrière un relai

Imaginons que je possède une machine_publique accessible sur le net à l'adresse 80.80.80.80

    moule@machine_publique> ./server.sh 6666 myserver:22
    -----------------------------------------------------
    Running ssh server as moule
    Listening on port 6666
    Authorized destinations: myserver:22
    Authorized keys file: /home/user/.ssh/authorized_keys
    -----------------------------------------------------
    Server listening on 0.0.0.0 port 6666.

Depuis n'importe où sur le net, on ouvre le tunnel:

    user@some_machine> ./access.sh moule 80.80.80.80 6666 10000 myserver 22

Et, depuis un autre terminal:

    user@some_machine> ssh -p 10000 localhost
    Welcome to the world of Moules!
    user@myserver> 

Il faut bien sûr que la clé publique de user soit dans les authorized_keys de moule sur machine_publique et sur myserver.

Reverse tunneling for fun!

On imagine maintenant qu'on désire accéder à une machine work depuis home (ip 95.95.95.95). Le port 6666 de home est ouvert sur le net.

    moule@home> ./server.sh 6666 localhost:*

Depuis le boulot:

    serious@work> ./give_access.sh moule 95.95.95.95 6666 10000 localhost 22

Un peu plus tard, en rentrant:

    moule@home> ./access.sh moule localhost 6666 15000 localhost 10000
    moule@home> ssh serious@localhost -p 15000
    serious@work>

On peut donc remonter le tunnel créé depuis work. C'est ce qu'on appelle du reverse tunneling. Et c'est précisément ce qui m'intéressait au départ!

Autres possibilités

On peut bien sûr accéder à autre chose qu'un serveur ssh (redirection http, imap, …)

La sécurité par l'exemple

Pour illustrer à quoi sert la restriction de destinations, voici un exemple (entièrement en local) ouvrant un tunnel vers le port 22 de github.com.

user@pc> ./server.sh 6666 localhost:*
user@pc> ./access.sh user localhost 6667 10000 github.com 22

On voit apparaître sur le terminal du serveur:

Postponed publickey for user from 172.17.0.1 port 37252 ssh2 [preauth]
Accepted publickey for user from 172.17.0.1 port 37252 ssh2: RSA 
user@pc> ssh git@localhost -p 10000
ssh_exchange_identification: read: Connection reset by peer

Sur le terminal du serveur:

Received request to connect to host github.com port 22, but the request was denied.

Sur le terminal ouvrant l'accès:

channel 1: open failed: administratively prohibited: open failed

On refait cette fois l'expérience en autorisant la destination github.com:22

user@pc> ./server.sh 6666 localhost:* github.com:22
user@pc> ssh git@localhost -p 10000
Hi second-reality! You've successfully authenticated, but GitHub does not provide shell access.

Cette fois, cela fonctionne bien!

Ainsi, on possède un contrôle très fin sur ce qui peut-être ouvert depuis une machine extérieure.


Description

La petite originalité de ce projet, c'est l'utilisation de Docker pour conteneuriser le serveur SSH.

Je voulais une solution qui:
- soit techniquement sûre
- soit simple et sans installation
- ne dépende pas d'une distribution particulière
- même en cas d'intrusion par un attaquant, que celui-ci ne puisse pas accéder à mes données, clés, ou celles d'une machine ayant ouvert un tunnel.
- ne demande pas de bidouiller mon sshd_config
- n'expose pas le serveur ssh de ma machine sur internet.
- que mon serveur ssh ne soit pas nécessairement executé par root
- permette de contrôler finement les destinations des tunnels

Aussi étonnant que celui puisse paraître, en dehors de quelques projets similaires sur Github (pour lesquels j'ai une confiance assez réduite), je n'ai pas vraiment trouvé d'outil dédié.

Quelques heures plus tard, le résultat est:
- un seul port est exposé sur Internet (redirection sur ma freebox), celui publié par le conteneur.
- les destinations des tunnels sont explicitement nommées
- J'ouvre mon serveur au besoin (et mon client essaye continuellement de s'y connecter).
- j'ai appris quelques trucs sur Docker et OpenSSH au passage.

Fichiers intéressants:
- le Dockerfile, contenant la config du serveur SSH: https://github.com/second-reality/reverse-tunnel/blob/master/Dockerfile

# run sshd on port $SSH_PORT, only allowing $AUTHORIZED_USER to connect
# and only authorizing forwarding to $AUTHORIZED_DESTINATIONS
# User running this is the one running the container
ENTRYPOINT /usr/sbin/sshd -p "$SSH_PORT" -D\
# show log of connections on stderr
 -e\
# keep clients alive
 -o ClientAliveInterval=180 -o ClientAliveCountMax=2\
# restrict local tunneling to only some destinations
# This is the heart of security!
 -o PermitOpen="$AUTHORIZED_DESTINATIONS"\
# allow anyone to access forwarded ports and not only localhost
 -o GatewayPorts=yes\
# only allow a specific user to connect (the one running container)
 -o AllowUsers="$AUTHORIZED_USER"\
# prevent execution of any command
 -o ForceCommand="/No/Shell/Available/ONLY_TUNNELING_IS_POSSIBLE"\
# other params (man sshd_config)
 -o UsePAM=no\
 -o PasswordAuthentication=no\
 -o AllowStreamLocalForwarding=no\
 -o AllowAgentForwarding=no\
 -o AllowTcpForwarding=yes\
 -o AuthenticationMethods=publickey\
 -o MaxAuthTries=1\
 -o PermitRootLogin=no\
 -o PermitTunnel=yes\
 -o PrintMotd=no\
 -o PidFile=none\
docker run --rm=true -p $ssh_port:$ssh_port $terminal\
  -v $authorized_keys:$authorized_keys:ro\
  -v /etc/passwd:/etc/passwd:ro \
  -v /etc/group:/etc/group:ro \
  -e SSH_PORT=$ssh_port\
  -e AUTHORIZED_DESTINATIONS="$authorized_destinations"\
  -e AUTHORIZED_USER="$USER"\
  -u $(id -u)\
  reverse-tunnel || die "running server failed"

Pièges

Il existe plusieurs pièges possibles dans un projet comme celui-ci:
- oublier de bloquer la possibilité d'exécuter une commande sur le serveur SSH. Cela peut augmenter la surface d'attaque en cas d'intrusion.
- oublier de bloquer les destinations: Si on ne limite pas les destinations, on peut accéder à un port de la machine hôte (et à tout son LAN globalement), hors du conteneur! (oups!)
- Des petites blagues (classiques avec Docker) sur les droits des fichiers accédés dans le conteneur.


Conclusion

N'hésitez pas à jouer en local, ça fonctionne de la même façon! Il est notamment intéressant de jouer sur les destinations autorisées.

Note: Ouvrir un tunnel SSH vers une machine personnelle depuis votre lieu de travail peut-être considéré comme une faute professionnelle. Il s'agit d'une brèche de sécurité importante dans l'infrastructure de votre entreprise.

Si vous avez des retours, des critiques, ou des suggestions, je suis preneur! Si vous avez besoin d'un coup de main pour l'utilisation, je peux aussi aider.

Happy tunneling!

  • # On est en 2020

    Posté par  . Évalué à 5.

    Faut arrêter d’utiliser FTP. Il y a déjà SFTP et FTPS, on n’a pas vraiment besoin de FTP dans un tunnel SSH.

    • [^] # Re: On est en 2020

      Posté par  . Évalué à 4.

      Oui et non.
      Moi je vois l'avantage de faire passer tout et n'importe quoi dans le tunnel de façon transparente. Et de l'extérieur on verra juste une connexion ssh et rien d'autre. Pas besoin non plus d'avoir 36 services en écoute sur l'extérieur juste le service ssh, le reste sera simplement en écoute sur localhost par exemple.

    • [^] # Re: On est en 2020

      Posté par  . Évalué à 2.

      Je suis en accord avec toi, j'ai simplement pris ftp comme exemple d'un protocole "classique" non sécurisé.

  • # diminuer la surface d'attaque

    Posté par  (site web personnel) . Évalué à 3.

    utiliser une Debian light comme Minideb ou Debian-stretch, ou une Alpine Linux, par exemple

    ウィズコロナ

  • # Stunnel dynamique

    Posté par  . Évalué à 2.

    En lisant j'ai mieux compris la différence avec stunnel.

    Stunnel va faire le tunnel vers une série de connexions paramétrées en avance.

    Alors qu'avec ton projet, c'est le client qui décide du tunnel qu'il veut créer, le serveur ne fait que vérifier que c'est autorisé.

    Très intéressant. C'est deux cas d'utilisation distinct.

    • [^] # Re: Stunnel dynamique

      Posté par  . Évalué à 2.

      À ma connaissance, stunnel ne fait qu'ajouter une couche SSL à une connexion existante (pour un client, ou un serveur), et rien d'autre.

      Typiquement, tu as un serveur qui ne parle que http. Tu peux utiliser stunnel pour avoir SSL "gratuitement" par dessus.

      Pour vulgariser:
      cat mon_fichier | stunnel | OVER_INTERNET | stunnel | cat, donne mon fichier, mais transmis de façon chiffré.

      Un tunnel SSH permet davantage. Il offre bien sûr le chiffrement de la connexion, mais de plus, il offre un tunnel qu'on peut établir dans les deux sens, ainsi que la notion de port forwarding (rediriger un port distant sur un autre local et inversement).

      Du coup, je dirai plutôt que stunnel est fait pour "décharger" le calcul de SSL sur un point d'entrée donné, et avoir un serveur qui parle en "clair" derrière. En tout cas, je l'avais connu dans ce contexte (car c'est souvent compliqué et error-prone de gérer SSL dans ton appli).

      • [^] # Re: Stunnel dynamique

        Posté par  . Évalué à 2.

        Oui ce que tu dis est exact. Mais le cas d'utilisation c'est aussi effectivement de sécuriser des connections de logiciels (éventuellement) tiers, alors que ceux-ci l'ignorent complètement.

        Je l'utilise en production car il est très résilient et facile à déployer.

  • # Ais je compris ?

    Posté par  (site web personnel) . Évalué à 2. Dernière modification le 08 janvier 2020 à 11:37.

    Bonjour,

    Petites questions :

    Le cas qui m'intéresse, c'est le deuxième. À savoir, accéder à la machine du boulot depuis chez moi, facilement.

    Tu n'as pas la possibilité de passer par un VPN professionnel ou mieux pas d'accès SSH à ton boulot

    C'est peut être pas toi qui gère les accès externes

    Ou tu ne veux pas de trace de tes connexions ;) ce qui peut être intéressant …

    Note: Ouvrir un tunnel SSH vers une machine personnelle depuis votre lieu de travail peut-être considéré comme une faute professionnelle. Il s'agit d'une brèche de sécurité importante dans l'infrastructure de votre entreprise.

    Sans rire c'est SSH le problème ou la machine personnelle ?

    Utilisation de protocole non sécurisé comme ftp

    ftp + ssh C'est possible depuis quand ? (non pas sftp …)
    parfois je me dis qu'il faudrait quand même que je me tienne au courant de certaines évolutions …

    Sinon

    je trouve l'idée intéressante, ne serait que pour reculer les limites d'utilisation d'un outils comme SSH, à étudier …

    • [^] # Re: Ais je compris ?

      Posté par  . Évalué à 0. Dernière modification le 08 janvier 2020 à 14:54.

      Je n'ai pas d'accès SSH ni de VPN au boulot. N'étant pas IT, c'est difficile pour moi de pousser une telle décision.

      Mon but, c'est juste de pouvoir lancer une commande que j'aurais oublié facilement depuis la maison, et avoir le résultat le lendemain.

      Le problème, c'est la machine personnelle. Elle ne correspond pas à la politique IT de ta boîte, et ça peut faire criser certains d'ouvrir une connexion à l'intérieur du réseau "sécurisé" de ta boîte depuis ta machine. Si un jour j'ai un souci (ça demanderait du deep packet inspection au minimum), je pourrais clairement défendre ma solution. Et puis au fond, c'était juste fun comme idée ;)

      Le protocole n'est pas ssh + ftp. C'est ftp, redirigé à travers une connexion ssh. Derrière, ton serveur à la maison transfère en clair avec le FTP final. Mais tu peux avoir un peu plus de confiance en ton FAI que dans le wifi du café du coin.

      Ce que tu dis le fait ne pas laisser de traces est pertinent aussi. Un tunnel SSH est très couramment utilisé pour laisser une backdoor sur une machine sur laquelle un attaquant s'est introduit.

      • [^] # Re: Ais je compris ?

        Posté par  (site web personnel) . Évalué à 2.

        Si j'ai bien compris :

        tu laisse un tunnel de ton boulot vers ta machine relais
        puis tu passes par ta machine relais pour te connecter

        Dans ce cas rajoute un couche Tor pour te connecter a ta machine relais depuis chez toi (avec Tails en VM par exemple)
        comme cela si c'est détecté ils penseront qu'ils s'agit d'une attaque de méchant pirate …

        Ceci dit dans une entreprise "normale" il n'y en pas 36 capable de bricoler ce genre de choses un "petit peu technique" … donc tu es facilement repérable … (connexion a linuxfr.org, magazine linux mag ou Misc dans ton sac ou sur ton bureau, T-shirt anonymous … )

        C'est toujours l'humain qui est faillible

        • [^] # Re: Ais je compris ?

          Posté par  . Évalué à 1.

          Plus exactement, ma machine du boulot essaye (constamment, 1 fois/30sec) d'ouvrir un tunnel vers une ip que je contrôle.

          Lorsque je veux y accéder, j'ouvre le serveur sur ma machine perso, le tunnel est alors créé. Je ne laisse pas ma machine perso allumée constamment, et encore moins le serveur ouvert.

          Je peux alors me connecter à la machine du boulot.

          Je ne cherche pas spécialement à me cacher (sinon écrire un article en mon nom sur linuxfr serait quelque peu stupide), mais si un jour on vient me voir, j'aurais de quoi échanger techniquement.

          • [^] # Re: Ais je compris ?

            Posté par  . Évalué à 5.

            Plus exactement, ma machine du boulot essaye (constamment, 1 fois/30sec) d'ouvrir un tunnel vers une ip que je contrôle.

            ils vont t’adorer les gars qui vont faire le prochain audit sécurité de la boîte!

            Linuxfr, le portail francais du logiciel libre et du neo nazisme.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.