Une compilation de documentations   { en , fr }

Les listes de révocation de clefs sous OpenSSH

Étiquettes:
Créé en:
Auteur:
Xavier Béguin
Version en anglais : Key Revocation Lists on OpenSSH

Les listes de révocation de clefs

Le serveur comme le client OpenSSH permettent tous deux de préciser des listes de révocation désignant des certificats ou des clefs qui ont été révoqués :

  • un certificat ou une clef désigné dans une liste de révocation utilisée par un client ne pourra pas être utilisé pour vérifier l'identité d'un serveur ;
  • de même, un certificat ou une clef désigné dans une liste de révocation utilisée par un serveur ne pourra pas être utilisé pour authentifier un client.

Ces listes de révocation peuvent fournies sous forme :

  • de fichiers texte donnant une liste de clefs révoquées ;
  • ou de fichiers binaires dans un format OpenSSH appelé liste de révocation de clefs (ou Key Revocation Lists, KRLs) générés à partir de fichiers texte par la commande ssh-keygen -k.

Création d'un fichier de révocation KRL

Utilisation de ssh-keygen -k

Les fichiers KRL peuvent être créé à l'aide de la commande ssh-keygen -k. Pour y ajouter ensuite des références à de nouvelles clefs ou certificats, il faudra utiliser également l'option -u. Le nom du fichier binaire KRL qui sera généré doit toujours être précisé à l'aide de l'option -f fichier.

Attention : utilisée sans l'option -u, l'option -k va écraser le contenu du fichier KRL existant sans avertissement.

Et quand cette option -u est présente, le fichier de sortie doit exister. Il peut donc être intéressant de prendre l'habitude de créer d'abord un fichier KRL vide avec l'option -k seule, sans fichier d'entrée :

$ ssh-keygen -k -f liste_revocation.krl
$ file liste_revocation.krl
liste_revocation.krl: OpenSSH key/certificate revocation list, format 1, version 0, generated Fri May 12 12:05:23 2023

On pourra ensuite systématiquement utiliser l'option -u avec -k pour éviter de perdre les informations déjà ajoutées au fichier. Par exemple, pour révoquer la clef contenue dans exemple.pub :

$ ssh-keygen -ku -f liste_revocation.krl exemple.pub
Revoking from exemple.pub

Pour alimenter le fichier KRL, ssh-keygen -k accepte des fichiers texte contenant :

  • une liste de clefs, chacune sur une ligne, c'est à dire un fichier comme celui-ci, par exemple :
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...4DE8KbbGA34JBTYEVOdOucjz herschel@laptop
    ecdsa-sha2-nistp256 AAAAE2VjZHNhLXN...W2yAX7g26E73LWSI= alice@ordi1
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...xioxrHTsQl2chRU0zuB/+yPz juliet@julietpc
    
  • ou une spécification KRL, c'est à dire une directive sur chaque ligne, suivie d'un deux-points (« : ») et de l'information spécifique à la directive. Chacune de ces lignes désignera une clef ou un certificat à inclure dans la liste ainsi produite. La section ci-dessous détaille le format de ces spécifications.

Les fichiers KRL étant binaires, il est nécessaire d'utiliser la commande ssh-keygen -Q pour en examiner le contenu. Par défaut, la commande retourne le code de sortie zéro si aucune des clefs mentionnées en argument n'est révoquée par le fichier KRL, et un code de sortie non nul seulement si au moins une des clefs est révoquée :

$ ssh-keygen -Q -f liste_revocation.krl ssh_host_ed25519_key.pub
ssh_host_ed25519_key.pub (root@server): REVOKED

Avec l'option -l, le contenu du fichier KRL est affiché :

$ ssh-keygen -Q -l -f liste_revocation.krl
# KRL version 0
# Generated at 20230512T120523

hash: SHA256:SHA256:ZvMiKrEjFWXWvZNIAraoHDb6Nwp+4mytu7jL5YyZwc8 # ssh-ed25519
hash: SHA256:66f3222ab1231565d6bd934802b6a81c36fa370a7ee26cadbbb8cbe58c99c1cf

# CA key ssh-ed25519 SHA256:e7wnSbMmyStx4K0+Mk3dj/03m/bI4Fk823EL0WdD8l4
id: Serveur de test

Les spécifications KRL

Dans une spécification KRL, un certificat ou une clef peut être désigné à l'aide des directives suivantes :

  • serial: pour désigner un certificat ayant un numéro de série différent de 0 (assigné à la création du certificat avec l'option -z de ssh-keygen). L'utilisation de cette directive nécessite de fournir la clef publique de l'autorité de certification avec l'option -s ac.pub ;
  • id: pour désigner un certificat par son identifiant (assigné à la création du certificat avec l'option -I de ssh-keygen). Notez que, bien que la commande d'affichage d'un certificat ssh-keygen -L affiche l'identifiant avec des guillements (sous le nom Key ID), il ne faut pas les utiliser dans la valeur donnée dans le fichier KRL, même si celle-ci contient des espaces. L'utilisation de cette directive nécessite là aussi de fournir la clef publique de l'autorité de certification avec l'option -s ac.pub ;
  • key: pour désigner une clef en l'incluant totalement ;
  • hash: pour désigner une clef par son empreinte SHA256 obtenue dans les journaux du serveur SSH ou avec la commande ssh-keygen -l -f key.pub.

Voici un exemple de fichier de spécification KRL comprenant un exemple de chacune des directives mentionnées :

serial: 42
id: Serveur de test
hash: SHA256:ZvMiKrEjFWXWvZNIAraoHDb6Nwp+4mytu7jL5YyZwc8
key: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHldYQOwXC+FRPWqI4ebXg7rbhd+ZW/VSfi44FTQFly5 beelzebot@hell

Les certificats et clefs désignés par ces directives (contenues, dans notre exemple, dans le fichier liste_nouvelles_revocations.spec) peuvent être ajoutées à une liste de révocation au format binaire KRL (ici liste_revocation.krl) avec la commande suivante (l'option -s ac.pub est nécessaire car nous avons utilisé les directives serial et id qui nécessitent la clef de l'autorité de certification) : 

$ ssh-keygen -ku -f liste_revocation.krl -s ac.pub liste_nouvelles_revocations.spec
Revoking from liste_nouvelles_revocations.spec

Ce fichier peut ensuite être utilisé par un serveur ou un client SSH.

Utilisation d'un fichier de révocation par un serveur SSH

Configuration à mettre en place

Pour utiliser une liste de révocation de clefs ou de certificats, le fichier correspondant doit être désigné dans la configuration du serveur OpenSSH (dans le fichier /etc/ssh/sshd_config sous Debian GNU/Linux) à l'aide de la directive RevokedKeys :

RevokedKeys /etc/ssh/liste_revocation

Comme on l'a déjà indiqué plus haut, ce fichier liste_revocation peut être :

  • un fichier texte contenant une clef publique sur chaque ligne ;
  • un fichier binaire au format KRL généré par la commande ssh-keygen -k comme détaillé plus haut.

Attention : si le fichier désigné par RevokedKeys ne peut pas être lu, toutes les connexions par clef seront refusées par le serveur.

Cette situation sera bien identifiée dans les journaux du système lors d'une connexion, avec un message du type :

error: Error checking authentication key ED25519 SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE in revoked keys file /etc/ssh/liste_revocation: No such file or directory

Il est donc nécessaire de créer le fichier avant de redémarrer le serveur SSH avec sa nouvelle configuration. On peut par exemple le créer vide avec la commande :

touch /etc/ssh/liste_revocation

Le serveur OpenSSH doit être redémarré pour relire sa nouvelle configuration :

service ssh restart

Les clients utilisant une clef ou un certificat figurant dans la liste de révocation ne pourront maintenant plus se connecter.

Bien que la documentation de la directive RevokedKeys dans le manuel sshd_config(5) mentionne uniquement la possibilité de lister des clefs SSH dans un fichier texte désigné par cette directive, il est en pratique également possible d'y faire figurer des certificats.

Cependant, l'inclusion de ce certificat va révoquer non seulement le certificat, mais également la clef SSH qui lui correspond.

Alors que, lorsqu'on désigne un certificat à révoquer depuis un fichier KRL (par son numéro de série ou son identifiant, par exemple), seul l'usage du certificat devient impossible, et l'utilisation de la clef SSH reste possible (bien entendu, si elle est autorisée dans le fichier authorized_keys du compte).

Il semble donc préférable de ne pas inclure de certificat en cas d'utilisation de fichier texte avec RevokedKeys car il s'agit d'un cas non documenté qui donne des résultats un peu inattendus.

Comportement du serveur

En cas de révocation d'une clef SSH :

  • si un client tente d'utiliser simplement la clef pour s'authentifier, les journaux du serveur SSH (auth.log sous Debian GNU/Linux) la mentionneront :
    error: Authentication key ED25519 SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE revoked by file /etc/ssh/liste_revocation
    
  • si un client tente de se connecter en présentant un certificat basé sur cette clef, les journaux du serveur SSH mentionneront la clef ainsi que le certificat :
    error: Authentication key ED25519 SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE revoked by file /etc/ssh/liste_revocation
    error: Authentication key ED25519-CERT SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE revoked by file /etc/ssh/liste_revocation
    

En cas de révocation d'un certificat SSH :

  • si ce certificat est présenté par un client, l'authentification sera refusée et les journaux du serveur SSH mentionneront l'usage empêché du certificat, avec l'empreinte SHA256 de la clef correspondante :
    error: Authentication key ED25519-CERT SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE revoked by file /etc/ssh/liste_revocation
    
  • si le client tente de se connecter avec la clef correspondant à un certificat révoqué, sa connexion sera acceptée (si, bien sûr, celle-ci figure dans le fichier authorized_keys du compte), puisque seul le certificat est révoqué.

Utilisation d'un fichier de révocation par un client SSH

Configuration à mettre en place

Pour révoquer des clefs ou certificats présentés par un serveur pour l'authentifier, il est nécessaire de désigner un fichier de révocation à l'aide de la directive RevokedHostKeys dans le fichier de configuration du client ~/.ssh/config :

RevokedHostKeys /home/herschel/.ssh/liste_revocation

Là aussi, ce fichier peut être :

  • un fichier texte contenant une clef publique sur chaque ligne ;
  • un fichier binaire au format KRL généré par la commande ssh-keygen -k comme indiqué plus haut.

Contrairement à d'autres directives du fichier ~/.ssh/config comme IdentityFile, la directive RevokedHostKeys n'accepte pas le ~ pour désigner le répertoire personnel du compte dans le chemin du fichier. Un chemin sous forme relative sera considéré relativement au répertoire courant du processus ssh. Il faut donc ici impérativement utiliser un chemin absolu (c'est du moins le cas sous OpenSSH 8.4).

Si le client ne peut pas lire le fichier de révocation, la vérification de l'identité du serveur échouera et la connexion sera impossible. Le client affichera un message comme celui-ci :

Error checking host key ECDSA SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI in revoked keys file /home/herschel/.ssh/liste_revocation: No such file or directory
Host key verification failed.

Lorsqu'un client reçoit, en se connectant à un serveur, un certificat qu'il a révoqué, il refusera de se connecter au serveur, même si une autre clef présentée par le serveur est présente dans le fichier known_hosts.

Comportement du client

Notons que, contrairement à ce qu'on pourrait imaginer un peu hâtivement, la révocation d'une clef d'un serveur ne va pas obligatoirement empêcher son identification et interdire toute connexion à celui-ci.

La révocation s'applique en effet à certaines clefs ou certificats et un serveur présente généralement des clefs et certificats de plusieurs types, que le client va considérer de manière séquentielle (selon un ordre de types d'algorithmes établi par la valeur de la directive HostKeyAlgorithms de la configuration du client).

En conséquence, si le client ne révoque pas tous les certificats et clefs présentés par un serveur, la connexion sera annulée uniquement si le premier certificat ou la première clef du serveur considéré par le client est désigné dans la liste de révocation utilisée par le client.

Dans ce cas, la connexion est annulée par le client avec un message explicite tel que :

$ ssh -i ~/.ssh/id_ed25519 lab.example.org
Host key ED25519-CERT SHA256:ZvMiKrEjFWXWvZNIAraoHDb6Nwp+4mytu7jL5YyZwc8 revoked by file /home/herschel/.ssh/liste_revocation
Host key verification failed.

En utilisant la commande ssh avec son option -v, le client mentionnera aussi le certificat donné par le serveur et qui a été révoqué :

$ ssh -v -i ~/.ssh/id_ed25519 lab.example.org
...
debug1: Server host certificate: ssh-ed25519-cert-v01@openssh.com SHA256:ZvMiKrEjFWXWvZNIAraoHDb6Nwp+4mytu7jL5YyZwc8, serial 0 ID "Serveur de test" CA ssh-ed25519 SHA256:e7wnSbMmyStx4K0+Mk3dj/03m/bI4Fk823EL0WdD8l4 valid forever
Host key ED25519-CERT SHA256:ZvMiKrEjFWXWvZNIAraoHDb6Nwp+4mytu7jL5YyZwc8 revoked by file /home/herschel/.ssh/liste_revocation
Host key verification failed.

Dans le cas où le client considère, avant toute clef ou certificat révoqué, une clef ou un certificat du serveur qui n'a pas été révoqué et auquel il a accordé sa confiance, le serveur sera bien authentifié et le client continuera l'établissement de la connexion en procédant normalement à sa propre authentification.

Pour référence, si le client rencontre une clef de serveur qu'il a révoquée, le message sera similaire et mentionnera la clef :

$ ssh -v -i ~/.ssh/id_ed25519 lab.example.org
...
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI
Host key ECDSA SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI revoked by file /home/herschel/.ssh/liste_revocation
Host key verification failed.