10 min de lecture
Écrire un remplacement à OpenSSH en utilisant Go (1/2)
La deuxième partie est en direct : Écrire un remplacement d'OpenSSH en utilisant Go (2/2) SSH est un protocole bien connu pour accéder aux serveurs distants et OpenSSH est l'implémentation la plus courante. Cet article expliquera comment construire un serveur et un client SSH en utilisant Go. TL;DR Pourquoi le serveur OpenSSH n'est pas suffisant dans un environnement distribué.

La deuxième partie est en direct : Écrire un remplacement à OpenSSH en utilisant Go (2/2)
SSH est un protocole bien connu pour accéder à des serveurs distants et OpenSSH est l'implémentation la plus courante. Cet article expliquera comment construire un serveur et un client SSH en utilisant Go.
TL;DR
Pourquoi le serveur OpenSSH n'est pas suffisant dans un environnement distribué
Quels sont les outils et bibliothèques disponibles en Go pour utiliser le protocole SSH
Quelques exemples d'implémentation
Git et SSH
Dans une plateforme en tant que service comme Scalingo, la manière standard de déployer une application est d'utiliser git push. En arrière-plan, git utilise simplement la commande ssh. Les deux lignes ci-dessous expliquent le lien entre eux :
En fait, il est possible de dire à git d'utiliser un autre client SSH, en définissant la variable d'environnement GIT_SSH.
Limitation d'OpenSSH
Pour authentifier un utilisateur sur un serveur distant en utilisant le serveur OpenSSH, la clé SSH publique de l'utilisateur doit être ajoutée dans le fichier ~/.ssh/authorized_keys de l'utilisateur cible. Si OpenSSH trouve la clé publique dans ce fichier, l'authentification est considérée comme réussie. Par défaut, il exécuterait le shell de l'utilisateur, défini par son compte.
Il est possible d'exécuter une commande personnalisée en la préfixant à la clé SSH publique dans le fichier authorized_keys :
Dans ce cas, au lieu d'exécuter le shell de l'utilisateur, il exécutera la commande “ssh-handler”. Notre premier prototype utilisait cette fonctionnalité pour authentifier et autoriser nos utilisateurs. Cependant, dès que vous voulez construire une véritable infrastructure distribuée, ce n'est plus suffisant. En effet, avec cette méthode, cela signifie que plusieurs hôtes doivent garder leur fichier authorized_keys contenant toutes les clés publiques de nos utilisateurs synchronisées. C'est deux problèmes en un : nous devions trouver un mécanisme de synchronisation, et, des données sensibles sont éparpillées sur plusieurs machines.
C'est pourquoi nous avons décidé qu'il était temps de construire quelque chose de plus robuste et évolutif en écrivant notre propre serveur SSH personnalisé, qui serait capable d'utiliser un backend personnalisé pour identifier nos utilisateurs et ensuite transmettre la connexion SSH à un autre hôte qui exécutera réellement l'opération GIT.
SSH dans le monde Go
Nous avons décidé d'écrire ce serveur SSH personnalisé avec Go pour différentes raisons. Excepté le fait que nous avions de l'expérience avec le langage, ce package officiel (http://godoc.org/golang.org/x/crypto/ssh) implémente tout ce dont nous avions besoin pour construire ce que nous recherchions, tout en gardant cela simple.
Chez Scalingo, nous cherchons à respecter le principe KISS. Si un logiciel est simple, il est plus facile de conserver la lisibilité, la modularité et la facilité de maintenance. D'ailleurs, c'est aussi pourquoi Go est devenu l'un de nos langages principaux.
Les RFC SSH
Alors que le package Go implémente la configuration des connexions SSH (ce qui inclut le transport et le cryptage), vous devez toujours comprendre et utiliser le protocole applicatif SSH pour construire votre logiciel.
Pour y parvenir, il est important de comprendre comment SSH fonctionne, les RFC suivantes définissent le protocole :
Architecture : https://tools.ietf.org/html/rfc4251
Protocole d'authentification : https://tools.ietf.org/html/rfc4252
Protocole de transport : https://tools.ietf.org/html/rfc4253
Gestion des canaux et protocole de connexion : https://tools.ietf.org/html/rfc4254 (probablement le plus utile lors de la construction de votre serveur)
Chaque fois que vous avez besoin d'explications sur une méthode ou une constante du package Go, il est assez simple de se référer aux RFC avec une simple recherche textuelle.
(Les RFC 4255 et 4256 concernent également SSH mais sont moins utiles dans ce contexte)
Exemples de code
1. Serveur de base
L'exemple de code suivant définit un simple serveur SSH : https://github.com/Scalingo/go-ssh-examples/blob/master/server.go
Ce serveur affiche uniquement le type de clé SSH utilisé pour l'authentification (le cas échéant), l'accepte, puis ferme la connexion.
Serveur :
Client :
Comme prévu, notre serveur Go réussit à communiquer avec OpenSSH, mais ensuite la connexion est immédiatement fermée.
2. Client de base
https://github.com/Scalingo/go-ssh-examples/blob/master/client.go
Utilisation :
Ce client a juste un travail, il se connecte à un serveur, crée une session, exécute une commande, puis imprime la sortie et se déconnecte.
Sortie :
Conclusion
Cet article présente notre problématique et comment utiliser le protocole SSH avec Go. Dans le prochain article, nous expliquerons comment nous utilisons cette bibliothèque pour résoudre nos vrais problèmes (Authentification, Autorisation, Proxy de connexion).
À suivre…
… Prêt ? La deuxième partie est ici : Écrire un remplacement à OpenSSH en utilisant Go (2/2)
Liens
Documentation du package : http://godoc.org/golang.org/x/crypto/ssh
Extraits de code : https://github.com/Scalingo/go-ssh-examples
Cet article était le 2ème post de la série #FridayTechnical, à la prochaine fois !
Crédits
Image Gopher par Renee French (Attribution Creative Commons 3.0) Puffy - Logo OpenSSH
— Léo Unbekandt, CTO @ Scalingo

Léo Unbekandt
Léo est le fondateur et CTO de Scalingo. Il a étudié en France en tant qu'ingénieur cloud (ENSIIE) et en Angleterre (Cranfield University). Il est responsable du développement technique de Scalingo et il gère notre équipe technique.
Restez informé
Recevez des articles et des mises à jour de la plateforme dans votre boîte de réception.
Prêt à déployer en toute confiance ?
Découvrez des déploiements sans temps d'arrêt, une mise à l'échelle automatique intelligente et une infrastructure entièrement gérée. Commencez à déployer vos applications sur Scalingo dès aujourd'hui.
Aucune carte de crédit requise • Déployez en quelques minutes • Annulez à tout moment






