Comprendre et maîtriser les clés SSH
Par Christophe Porteneuve • Publié le 13 septembre 2010 • 11 min

Git base toute sa gestion d’authentification sur le mécanisme des clés SSH. Ce système est d’ailleurs immensément utile de façon générale sous Linux, Unix et OSX, dès qu’il s’agit de s’authentifier sur une machine tierce. Afin d’avoir un maximum de confort lorsqu’on accède à un dépôt nécessitant une identification (lecture de dépôts privés ou écriture dans le cas général), il est donc important de bien maîtriser les clés SSH.

Ce billet tente de vous donner toutes les clés (ahem) pour comprendre et manipuler aisément vos identités SSH.

Après un topo rapide sur le principe des clés asymétriques, nous verrons rapidement quels algorithmes sont à favoriser, quelles tailles de clé sont acceptables, et les meilleures pratiques de protection de vos clés (tant en termes de passphrase que de gestion des droits d’accès à vos fichiers de clés).

Ces fondamentaux étant assimilés, nous pourrons vérifier si vous avez déjà des clés, comment en créer de nouvelles, et comment vous en servir efficacement et confortablement pour vos accès à des dépôts Git.

Principe des clés asymétriques

Quand vous travaillez avec des clés asymétriques, par principe, vous avez deux clés (on parle de paire de clés) : une clé publique, que vous pouvez diffuser librement, voire mettre à disposition sur un serveur de clés ; et une clé privée, qui constitue véritablement votre « identité », et ne doit jamais être diffusée : elle reste simplement présente dans votre dépôt de clés personnel.

Comme toujours en cryptographie, on peut faire deux choses avec une clé : chiffrer un contenu (l’encrypter) ou le signer (calculer une valeur unique, reposant sur le contenu concerné et sur votre clé privée, pour obtenir une valeur de signature, comme un cachet spécifique). Seule la clé « d’en face » (la publique si vous avez utilisé la privée, et inversement) permet de déchiffrer ou de vérifier la signature. Notez au passage que signer un contenu permet non seulement d’attester que vous êtes bien l’envoyeur (ou l’auteur, etc.), mais aussi que le contenu n’a pas été modifié après signature.

Une paire de clé permet donc de vous représenter vis-à-vis d’un système tiers, en lui fournissant à l’avance votre clé publique, pour ensuite communiquer avec lui à l’aide de votre clé privée ; puisque seules les clés d’une même paire peuvent se comprendre, le système distant est à même non seulement de vérifier que vous êtes bien celui (ou celle) que vous prétendez être, mais aussi que ce qu’il reçoit est bien ce que vous envoyé. Pas mal !

Si le sujet vous intéresse, vous trouverez une tonne d’infos sur Wikipedia. Mais si j’étais vous, je finirais cet article d’abord histoire de ne pas partir sur une tangente…

RSA vs. DSA

Il existe de nombreux algorithmes de chiffrement basés sur des clés asymétriques, mais les deux dominants, et de loin, son RSA et DSA, d’après les initiales de leurs auteurs respectifs. RSA est historiquement le premier, et DSA a été développé plus récemment, comme une alternative alors qu’RSA était encore breveté.

De nombreux didacticiels, articles et documentations exploitent RSA, mais vous pouvez choisir librement RSA ou DSA pour vos clés, du moment que vous utilisez une taille suffisante (voir ci-après).

Taille de clé

Une clé a une taille, exprimée en nombre de bits. Par exemple, les clés exploitées par les certificats de chiffrement des sites web utilisant la protection SSL (vous savez, ces URLs qui démarrent en https://, par exemple votre gestion de compte bancaire en ligne) sont généralement limitées, pour des raisons légales d’origine honteuse, à 256 bits. En revanche, vos propres clés ne font pas (ou plus, suivant le pays où vous vivez) l’objet d’une telle limitation.

À ce jour, une taille de 2Ko, c’est-à-dire 2048 bits (oui, 8 fois plus qu’un certificat bancaire !) est considérée raisonnablement sécurisée pour RSA, en tout cas pour un particulier. En gros, même si la toute-puissante NSA avait envie de casser votre chiffrage pour jeter un œil à ces données, il leur faudrait quelques heures pour y parvenir. Et pour qu’ils daignent vous allouer quelques heures de leur système, vous devez en gros être un très, très gros poisson.

Donc on est tranquilles.

Notez qu’en revanche une clé DSA fait obligatoirement 1024 bits (1Ko). C’est comme ça.

Passphrase

Vous avez certainement l’habitude voir le terme password, c’est-à-dire mot de passe. Et vous avez sûrement déjà rencontré des tas de systèmes, services et outils qui vous demandent de saisir un mot de passe, en lui imposant une taille minimum (ce qui est bien) et maximum (ce qui est parfaitement stupide et contre-productif). À cause de ce maximum, justement, ces systèmes insistent pour que vous mélangiez à loisir majuscules, minuscules, chiffres et symboles, et n’utilisiez pas de termes trop évidents (dates de naissances, prénoms, noms de vos animaux, mots basiques, segments de touches du clavier, etc.).

Du coup, tout le monde se retrouve forcé d’utiliser des mots de passe genre &dF@8^Xy+, qui sont tellement tordus qu’on s’empresse de les noter sur un papier, massacrant instantanément l’utilité du mot de passe en le rendant facile à découvrir en cas de besoin (surtout quand ledit papier est un Post-It™ collé sous le clavier, voire sur l’écran) (ne rigolez pas, je l’ai déjà vu) (plusieurs fois) (en fait, si ça se trouve, vous l’avez déjà fait) (gredin(e) que vous êtes).

Par contraste, une passphrase (pas d’équivalent français satisfaisant à ma connaissance, aussi essayez de le prononcer correctement, genre passfrayz) est une petite phrase, ou tout au moins un morceau de phrase, donc plusieurs mots. Et je dis bien mots, parce qu’en l’occurrence, utiliser de vrais mots et noms ne pose plus guère de problème, dès lors qu’on en a au moins 3 ou 4, surtout s’ils n’ont aucun rapport.

« Mais on m’a toujours dit que des vrais mots Saymal™ ! », me hurlez-vous avec consternation, le sourcil vengeur.

Oui, sauf dans des jolies passphrases. Pourquoi donc ? Parce que le niveau de complexité augmente de façon plus qu’exponentielle au fil des caractères, en particulier quand on commence à découper en mots. En cryptographie, on considère qu’un mot de passe, ou une passphrase, peuvent appartenir à plusieurs niveaux de sécurité, qui correspondent à la difficulté qu’on rencontre pour les casser. La recherche sur le sujet abonde et se met à jour chaque année, notamment au sein de conférences spécialisées comme la célèbre DEFCON.

Je suis assez fan de cet excellent article de Thomas Baekdal, qui illustre bien le sujet. Imaginons une passphrase qu’il faudrait des centaines d’années, voire des millénaires, dans l’état actuel de la technologie la plus avancée, pour casser par un moyen technologique. On qualifie une telle passphrase de « sécurisée à vie » (secure for life). Eh bien, pour obtenir une telle passphrase, il suffit de combiner au moins 3 mots, pas nécessairement sans rapport, pour un total d’au moins une dizaine de caractères. Voici quelques exemples de telles passphrases :

  • this is fun (sérieux ! Il faudrait au moins 25 siècles…)
  • j’aime les noix de cajou (le système solaire aura déjà implosé d’ici qu’on casse ça…)
  • des filles à la vanille
  • san pellegrino enterre badoit
  • i love to boogie
  • tu fais du vb dommage eliane
  • entre git et svn j’ai choisi
  • plutot crever qu’installer vista

Vous avez immédiatement perçu l’avantage monstrueux d’une bonne passphrase, lecteurs fûtés que vous êtes : non seulement c’est sécurisé à vie, mais en plus c’est carrément plus facile à mémoriser !

Bon, vous allez me rétorquer que c’est vachement plus long à taper, et là je vous répondrais que oui, mais qu’il existe des tas d’outils de type agents SSH, trousseaux de clés et systèmes de mémorisation de mot de passe (dans votre navigateur par exemple), qui sont de manière générale une bonne idée (surtout si vous leur mettez un mot de passe maître, à taper une seule fois par session, qui les déverrouille explicitement). Puisque nous parlons ici spécifiquement de clés SSH, nous aborderons plus loin comment éviter la saisie systématique de sa passphrase.

Parce que ne vous avisez surtout pas de « résoudre » le pseudo-problème de la longueur du texte en utilisant une passphrase vide. Ce serait complètement stupide, parce que ça reviendrait à ne pas du tout protéger votre clé ! Donc assurez-vous d’utiliser une bonne passphrase bien solide, et préférez les agents SSH (que nous verrons plus bas, je le répète) pour vous éviter des saisies multiples.

Vérifier ce qu’on a comme clé

Bon, il est l’heure de vérifier si vous avez déjà une paire de clés du bon type (DSA)…

Sur tous les systèmes Linux et Unix, vos clés SSH sont normalement stockées dans un dossier .ssh à la racine de votre profil. Ouvrez donc un terminal et tapez la commande suivante :

ls -lAF ~/.ssh

Si vous avez un message d’erreur (genre « je ne connais pas ce dossier ») ou un listing ne contenant que des fichiers style authorized_keys, config ou known_hosts, vous n’avez pas encore de clé exploitable. Ce que vous cherchez, ce sont des fichiers qui, classiquement, s’appellent id_dsa (la clé privée) et id_dsa.pub (la clé publique). Ce sont de bêtes fichiers texte, avec un peu d’enrobage autour de votre clé représentée dans un format appelé Base64. Par exemple, sur mon portable, le listing donne ça :

$ ls -lAF ~/.ssh
total 48
-rw------- 1 tdd tdd 90 déc 11 2009 config
-rw------- 1 tdd tdd 736 aoû 23 2007 id_dsa
-rw------- 1 tdd tdd 609 aoû 23 2007 id_dsa.pub
-rw------- 1 tdd tdd 736 jul 17 09:17 id_dsa_git
-rw-r--r-- 1 tdd tdd 609 jul 17 09:17 id_dsa_git.pub
-rw------- 1 tdd tdd 668 avr 6 22:53 id_dsa_sips
-rw-r--r-- 1 tdd tdd 23696 jul 24 11:07 known_hosts

Comme vous pouvez le constater, ma clé fondamentale date un peu (23 août 2007), et j’ai une deuxième paire dédiée pour Git (id_dsa_git), ce qui n’a rien d’obligatoire, ainsi qu’une troisième, dont je n’ai ici que la clé privée, et qui me sert encore à autre chose.

Vous n’avez pas de clé DSA, ou vous en avez une dont vous ignorez la passphrase pour quelque raison que ce soit ? Ou peut-être en voulez-vous une dédiée pour Git ? Pas de souci, on va en créer une nouvelle !

Créer une clé

L’outil de prédilection pour créer des clés (et un peu tout ce qui touche à la crypto) est le système OpenSSL. C’est un ensemble de bibliothèques et outils en ligne de commande, présent sur tous les Linux et Unix (entre autres), qui constitue le standard de facto. Dommage qu’il soit si mal documenté… Ici, on peut passer par une surcouche spécialisée dans les clés SSH, au travers de l’outil en ligne de commande ssh-keygen.

Pour créer une paire de clés DSA, on procède comme suit. Je suppose ici que vous allez changer le nom par défaut vers id_dsa_ga (pour Git Attitude), mais si vous laissez le nom par défaut, il suffit de taper Entrée à la question correspondante. Évidemment, utilisez votre propre chemin.

$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/tdd/.ssh/id_dsa): /Users/tdd/.ssh/id_dsa_ga
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/tdd/.ssh/id_dsa_ga.
Your public key has been saved in /Users/tdd/.ssh/id_dsa_ga.pub.
The key fingerprint is:
65:31:7e:ee:49:3a:66:cd:92:7b:02:2b:bf:b3:1a:79 tdd@CodeMagic.local
The key’s randomart image is:
+--[ DSA 1024]----+
| o |
| . o |
| + . |
| o o |
| S o |
| .. B . |
| o EoB = |
| .ooo.+. |
| .+++.o |
+-----------------+

Suivant votre version de ssh-keygen, vous n’aurez pas forcément le randomart à la fin (et en vrai, on s’en fout), et la ligne qui suit « The key fingerprint is: » sera totalement spécifique à votre propre exécution de la commande. Chaque paire de clés a une empreinte unique.

Et de fait, regardez un peu vos clés toutes neuves (vous aurez naturellement des valeurs différentes de celles présentées ici, celle de la privée étant d’ailleurs tronquée par mes soins :)

$ cat ~/.ssh/id_dsa_ga
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,6ED59B013D8A361F

pB5eHHpvXxoz6i1jFzlKANv9W6SeHw664PV/1A90acR/Mw/ERQvTQKo3TaLaFhkb

NwhQFyxZZty2hn6xrv5UIAGTpjk+P2+waRmSno1Vg1x0epCp45kvFRv9AiXsOpt4
RgzPC5+a6kjPf8EtyozGoQ==
-----END DSA PRIVATE KEY-----
$ cat ~/.ssh/id_dsa_ga.pub
ssh-dss AAAAB3NzaC1kc3MAAACBAJhbQcZK8lFMvpw7trbFj51Sqjd9nKBu2xkw/kvUAQlPQPaIRLOiq92fxp+jzp97xDqpwFnvU++ptUiB1nQQ8oq8l5t5QuHwfMMnSDMXhWf2235i4Lw2DtRTbxs0UQJ1l+QxO/AjlV/POcFpq6Z0PKMosi8TslqqPaqAbQtiEX2DAAAAFQDaK1EZY12itrt0lomTAOT0QATilwAAAIAK9C0YTR0T82r7TFheo/+vU6dS9KCypEjR7rEVf7MxCJLd9MQNkVTJe7XCFnYeT9oz7h8NbYHGyDQr7EZGIchtiju6EPFWuQWEAJAHq7z9s9ygoVqyWSQo0y/6riihJk5bo+Etj//OdwndlfKg0c6UGBFg8T2i6nKsbmMMEAI+XAAAAIA+bPjEeoZhwLuCp3Bv0+B4mWgGqnb2IhRSVDQNYeHIofhiSY7prVB+O1iQhrN/EJlygkaFWNaVlPmxrXa+8i+ZGWeVlAaKJdSAsDawNjOaHTi6/Cfqm7NTrLIIeOcjjxwrPLPZ3v0tP8MFjhYFdgjooYjTDzqQmpCGVSA4hXtqhg== tdd@CodeMagic.local

Notez que les clés publiques sont généralement formatées sur une seule ligne ; dans une liste de clés (par exemple le fichier ~/.ssh/authorized_keys, qui liste les clés publiques dont les titulaires peuvent accéder à votre compte via SSH), on a donc en général une clé par ligne. La fin de la clé publique est son commentaire, qui vaut par défaut « identifiant@machine », mais peut être changé.

Dernière info sur la manipulation des fichiers de clé : on peut changer la passphrase d’une clé SSH avec la ligne de commande suivante :

$ ssh-keygen -p -f ~/.ssh/le_fichier_de_cle

La commande vous demandera votre ancienne passphrase, puis la nouvelle avec une double saisie (initiale puis de confirmation). Pratique si vous aviez saisi une passphrase un peu pourrie, par exemple. En revanche, si votre clé est compromise (vous avez des raisons de penser qu’un tiers s’est approprié votre clé privée), ne changez pas la passphrase (ça ne servira à rien) : changez de clé !

Agents SSH

Un agent SSH est un outil intégré à votre système d’exploitation qui vous permet de ne saisir la passphrase d’une clé qu’une seule fois (pendant la durée de vie de l’agent, généralement limitée à votre session, entre connexion et déconnexion).

OS X intègre cette fonction dans son outil plus général de Trousseau d’Accès (Keyring) depuis Leopard (10.5). Avant cela (par exemple Tiger, la 10.4), il fallait ruser comme décrit dans cet article. La première utilisation d’une clé entraîne l’affichage d’une demande de passphrase, et la possibilité de stocker celle-ci dans le trousseau d’accès pour éviter des saisies supplémentaires durant la session.

Ubuntu et ses variantes intègrent cette fonction aux principaux gestionnaires de fenêtre (Gnome, KDE, etc.). Le workflow est similaire à celui d’OS X : la première utilisation entraîne une demande de passphrase avec persistence dans l’agent.

Pour les autres distributions Linux et gestionnaires de fenêtre, je ne sais pas trop si un agent est déjà disponible ou pas. Vous pouvez le vérifier en ouvrant un terminal puis en tapant :

set | grep SSH_AUTH_SOCK

Si vous ne voyez rien s’afficher, vous n’avez pas d’agent actif ; si vous voyez quelque chose (probablement du genre /var/run/….sock), alors vous en avez un.

Si vous n’avez pas d’agent actif, vous pouvez en lancer un manuellement à l’aide de la bien-nommée commande ssh-agent. Celle-ci crée un processus résident (un daemon) et affiche la série de commandes à balancer dans l’environnement (ou dans chaque terminal) pour qu’il soit au courant que l’agent existe, et donc qu’il essaie de s’en servir. Ces commandes consistent généralement juste à définir les variables d’environnement SSH_AUTH_SOCK et SSH_AGENT_PID. Du coup quand on lance un agent à la main dans le shell courant, on récupère généralement son affichage pour l’exécuter aussi sec, comme ceci :

$ eval `ssh-agent`
Agent pid 23038

Évidemment, vous verrez un autre numéro de processus (pid), mais le principe est le même.

À partir de là, à vous de tester le comportement lors de la première utilisation d’une clé SSH : si vous voyez une interception globale vous demandant de saisir la passphrase et proposant de la stocker dans l’agent, tout baigne. Si ce n’est pas le cas, vous allez devoir ajouter la passphrase à l’agent manuellement, en utilisant la commande ssh-add. Dans ce cas, soit vous avez une seule clé, et vous n’avez pas besoin de la préciser, soit vous en avez plusieurs et il faut indiquer laquelle :

$ ssh-add ~/.ssh/id_dsa_ga
Enter passphrase for /Users/tdd/.ssh/id_dsa_ga:
Identity added: /Users/tdd/.ssh/id_dsa_ga (/Users/tdd/.ssh/id_dsa_ga)

Après ça, la passphrase est automatiquement exploitée pendant toute la durée de vie de l’agent.

Ce type de manip’ est notamment utile quand on se connecte sur un serveur de production où on va faire une série de git pull, git submodule update, etc. et où on veut éviter de taper sa passphrase une tonne de fois. On commence par configurer l’agent, ajouter sa clé, et hop ! On est prêt à rouler.

Enfin, pour ce qui est de Windows, avec msysGit spécifiquement, vous trouverez quelques instructions pour lancer automatiquement ssh-agent sur cette documentation chez GitHub.

Publier sa clé publique ?

Les clés asymétriques ne sont pas seulement utiles pour SSH et les systèmes se greffant par-dessus. Elles sont aussi, par exemple, le moyen privilégié pour (dé)crypter ou signer numériquement (ou les deux) les e-mails. Je rêve du jour où tout le monde saura utiliser correctement le medium e-mail : pas de pièces jointes énormes ou débiles, pas de liste d’e-mails destinataires visible par tout le monde, pas de HTML pourri rempli de Comic Sans MS… et l’habitude de signer les e-mails importants. Ce dernier point, notamment, ouvrira le chemin des e-mails comme moyen valide de communication à valeur légale, par exemple avec votre banquier, votre notaire, votre avocat, etc.

Si le sujet vous intéresse, jetez par exemple un œil au client de messagerie Thunderbird et à son extension Enigmail, basée sur l’outil libre GnuPG (naturellement, il existe d’autres possibilités techniques autour d’Apple Mail, de GMail et j’en passe).

Dans un tel contexte, il est important de pouvoir facilement récupérer la clé publique de quelqu’un, soit parce qu’on veut lui envoyer un contenu confidentiel (on va donc le chiffrer avec la clé publique du destinataire, dont seule la clé privée pourra déchiffrer), soit parce qu’on a reçu un e-mail signé numériquement de cette personne (grâce à sa clé privée), et qu’on veut vérifier que ça vient bien d’elle, et que le contenu n’a pas été altéré (ce qu’on peut faire uniquement à l’aide de sa clé publique).

Bien entendu, la personne en question peut nous avoir, au préalable, transmis sa clé publique. Encore faut-il pouvoir faire confiance au mécanisme qui a fait cette transmission (il existe des moyens, dont l’empreinte de la clé, mais ce n’est pas le sujet de cet article). Un autre moyen plus général est, pour la personne, de publier sa clé publique aux yeux de tous. Pour cela, il existe des serveurs de clés. La plupart sont gratuits, et les plus connus sont répertoriés par les principaux systèmes exploitant des clés. En voici quelques-uns :

Et Git dans tout ça ?

La plupart des hébergements de dépôt Git reposent sur des clés SSH publiques pour identifier les personnes ayant un accès aux dépôts. Lorsque vous accédez à un dépôt authentifié, que ce soit en protocole git://… ou git@…, le système SSH sous-jacent va passer en revue vos clés privées au regard des clés publiques qu’il connaît, et s’il trouve une correspondance, vous demander la passphrase (à moins qu’un agent ne la lui fournisse tout seul) puis engager la suite des opérations.

Dans le cadre des ateliers Git Attitude, lorsque nous étudions l’interaction avec des dépôts distants, j’ai besoin de disposer de clés publiques dont vous avez l’homologue privée, afin de configurer vos accès au serveur Gitosis que nous utilisons. Vous recevez dans vos convocations une demande pour me fournir cette clé à l’avance, avec un lien vers cet article si vous vous sentez déboussolés :-)

J’espère que cet article vous a été utile, et vous a permis de mieux comprendre les clés SSH et leurs meilleures pratiques d’utilisation. Si vous avez des questions, commentaires ou corrections, les commentaires sont là pour ça !