Utilisation habituelle des clefs SSH
La role de la confiance entre client et serveur
Les clefs SSH sont des outils puissants permettant notamment de garantir l'identité d'un interlocuteur sur le réseau sans avoir à échanger de secret partagé.
Pour se connecter à un serveur par SSH, il est nécessaire que le client ait confiance en l'identité de ce serveur (pour éviter les attaques de type attaque de l'homme du milieu). Et, bien entendu, avant d'accorder l'accès au système, le serveur doit avoir confiance en l'identité du client qui se connecte, pour n'autoriser l'accès au serveur qu'aux personnes autorisées.
La plupart du temps, ces deux types indépendants de vérification d'identité sont réalisés grâce aux clefs SSH de la manière que nous allons décrire ci-dessous avant de nous intéresser à l'utilisation des certificats SSH pour ces mêmes opérations.
Authentification du client par le serveur
Pour que le serveur fasse confiance au client qui tente de se connecter,
l'administrateur du système doit placer la clef SSH publique de chaque
utilisateur⋅rice dans le fichier ~/.ssh/authorized_keys
du compte.
Lorsque le client se connecte, celui-ci utilise la clef SSH privée de
l'utilisateur⋅rice, dont le serveur peut vérifier l'authenticité grâce à la
clef publique correspondante conservée dans le fichier ~/.ssh/authorized_keys
du compte auquel le client tente de se connecter.
Authentification du serveur par le client
Lors de sa première connexion à un serveur, le client enregistre une clef publique fournie par le serveur en supposant qu'il s'agit bien de la clef serveur de l'hôte auquel il cherche à se connecter.
Avant de lui faire confiance cependant, le client va demander à l'utilisateur⋅rice d'accepter la connexion et l'enregistrement de la clef du serveur. Cela se présente de cette manière :
~$ ssh lab.example.org
The authenticity of host 'lab.example.org (192.168.1.3)' can't be established.
ECDSA key fingerprint is SHA256:wxocsOPNEfYuuTcXGuitKR8RUowpGbgpXTEsXXirAFI.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'lab.example.org' (ECDSA) to the list of known hosts.
Si l'utilisateur⋅rice accepte de se connecter à ce serveur, le client va
enregistrer la clef du serveur dans son fichier ~/.ssh/known_hosts
(indexée
avec une valeur de hashage calculée avec le nom du serveur tel qu'il a été
donné au client SSH).
La commande ssh-keygen -F <hôte>
permet de rechercher la clef d'une machine
dans le fichier ~/.ssh/known_hosts
. Par exemple :
~$ ssh-keygen -F lab.example.org
# Host lab.example.org found: line 133
|1|4M/wUtH5ptcDaJ7BwKPcpci6iZA=|Ba7Gk24pQ4qdIg4hR5KVIjdGo7Y= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNo(...)3+Ciz9DgKW2yAX7g26E73LWSI=
Lors des connexions suivantes, le client va rechercher de la même façon dans le
fichier ~/.ssh/known_hosts
la clef publique du serveur. Si la clef publique
ainsi conservée correspond bien à la clef privée utilisée par le serveur, le
client va faire confiance au serveur et procéder ensuite à sa propre
authentification. Si ce n'est pas le cas, le client interrompt la connexion et
affiche à l'utilisateur⋅rice un message lui indiquant que le serveur auquel il
ou elle tente de se connecter n'a plus la même clef SSH que lors de sa dernière
connexion, ce qui indique que le serveur n'est peut-être pas celui auquel il ou
elle souhaite se connecter.
On remarque qu'une faiblesse du protocole existe à ce niveau puisqu'à la première connexion, l'utilisateur⋅rice qui accepte aveuglément la clef SSH du serveur prend le risque de se connecter à un serveur qui n'est pas celui qu'il croit être.
Ce risque peut être écarté si les clefs publiques des serveurs sont distribuées
par d'autres moyens aux utilisateur⋅rice⋅s pour les ajouter à leur fichier
known_hosts
, leur permettant ainsi d'authentifier le serveur dès leur
première connexion.
Une variante de cette solution est facilitée dans les versions récentes
d'OpenSSH où, comme on le voit dans l'exemple ci-dessus, au lieu de répondre
yes
ou no
à la question du client demandant s'il faut se connecter à ce
serveur, celui-ci donne la possibilité de fournir l'empreinte de la clef SSH
attendue. La connexion se fera alors uniquement si celle-ci correspond bien à
l'empreinte de la clef donnée par le serveur (ce qui est plus fiable que de
vérifier visuellement l'empreinte affichée par le client).
Utilisation de SSH basée sur les certificats
Comme on vient de la voir ci-dessus, dans l'utilisation habituelle des clefs SSH :
- le serveur authentifie les clients à l'aide de clefs SSH conservées dans les
fichiers
~/.ssh/authorized_keys
des comptes utilisateur⋅rice⋅s ; - le client authentifie le serveur auxquel il se connecte grâce à la clef
publique présentée par le serveur à la première connexion et conservée
ensuite dans un fichier
known_hosts
.
Avec les certificats, le serveur comme le client continuent d'utiliser leur paire de clefs, mais chacun utilise en plus un certificat qui consiste en une signature de la clef SSH à laquelle le certificat est associé, faite par une clef représentant l'autorité de certification, augmentée d'une identité, d'un nom-clé (c'est la traduction que je propose d'utiliser dans ce document pour le terme technique anglais principal), et de quelques options.
Ainsi, au lieu d'accorder leur confiance aux clefs publiques conservées dans
les fichiers authorized_keys
, le serveur n'aura à accorder sa confiance qu'à
une seule clef publique, représentant l'autorité de certification qui crée ces
certificats et permet de vérifier l'authenticité des clefs SSH.
De même, au lieu que le client ait à maintenir une liste de clefs publiques de
confiance des serveurs dans son fichier known_host
, il n'aura qu'à faire
confiance à la clef publique de l'autorité de certification qui fournit les
certificats SSH.
Mise en œuvre pratique des certificats
Deux autorités de certifications distinctes
En pratique, la paire de clefs représentant l'autorité de certification qui génère les certificats n'est qu'une simple paire de clefs SSH, comme celles utilisées pour l'authentification des serveurs ou des clients.
Il est conseillé d'utiliser une paire de clefs d'autorité de certification différente pour les serveurs et les clients. Rien n'y oblige, mais c'est une mesure cohérente puisque l'authentification des serveurs et celle des clients, bien qu'utilisant la même méthode, sont deux opérations indépendantes.
Génération des clefs des autorités de certification
On génère tout d'abord les deux paires de clefs qui nous serviront d'autorités
de certification (AC), l'une pour les certificats serveurs, l'autre pour les
certificats clients, à l'aide de la commande ssh-keygen
, comme on le fait
pour toute clef SSH.
Ces clefs peuvent être de n'importe quel type, nous utiliserons ici ed25519
(ecdsa
ou d'autres types peuvent aussi être utilisés). L'option -C
utilisée
ci-dessous nous permet de bien différencier les deux clefs publiques en
précisant un commentaire :
Il est conseillé d'utiliser une longue phrase de passe pour protéger correctement ces clefs particulièrement sensibles, et de ne les utiliser que sur un serveur correctement isolé.
L'option -a
utilisée dans les commandes ci-dessus n'est pas strictement
nécessaire mais permet de préciser le nombre d'applications de la fonction de
dérivation de clef (KDF, key derivation function) utilisé pour protéger la
clef privée par sa phrase de passe.
Lorsque cette option n'est pas précisée, par défaut 16 applications sont effectuées. Comme l'indique la page de manuel ssh-keygen(1), (en anglais), « un nombre plus important résulte en une vérification de la phrase de passe plus lente et une meilleure résistance au déchiffrement par force brute du mot de passe (au cas où les clefs étaient volées) ». La phrase de passe n'étant vérifiée que lors du chargement de la clef et le ralentissement de cette vérification étant peu important, il est recommandé d'augmenter ce nombre.
Voici par exemple ce qu'afficherait une de ces commandes lors de son utilisation :
# ssh-keygen -a 256 -t ed25519 -C 'AC serveurs' -f ac_serveurs
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ac_serveurs
Your public key has been saved in ac_serveurs.pub
The key fingerprint is:
SHA256:e7wnSbMmyStx4K0+Mk3dj/03m/bI4Fk823EL0WdD8l4 AC serveurs
The key's randomart image is:
+--[ED25519 256]--+
| |
| |
| . . |
| . = |
| . +S. . +E|
| + +o+ .o.+|
| o =.ooB..+o.|
| o = +.*o+=.B*|
| +.o.+.oo.*=*|
+----[SHA256]-----+
Création d'un certificat client
Un certificat est généré pour un client en signant, à l'aide de la clef de
l'autorité de certification (ac_clients
dans notre cas), la clef publique
générée par l'utilisateur⋅rice :
Dans cette commande :
-s /chemin/vers/ac_clients
indique le chemin vers la clef privée représentant l'autorité de certification à utiliser pour les certificats clients ;-I id_clef
indique une identité qui peut être choisie librement et contenir des espaces (les caractères accentués ne sont toutefois pas correctement affichés). Elle sera consignée dans les journaux système lors de l'utilisation du certificat et pourra être utilisée en cas de révocation du certificat si celui-ci n'a pas de numéro de série (voir mon article « Les listes de révocation de clefs sous OpenSSH ») ;-n nom1,nom2,…
précise un ou plusieurs noms-clés (principals en anglais) dans le certificat :- pour un certificat client, au moins un nom-clé doit être précisé pour désigner le nom du compte sous lesquels l'utilisateur⋅rice pourra se connecter (on peut en préciser plusieurs, séparés par des virgules),
- si le nom du compte utilisateur⋅rice cible n'est pas présent dans les
noms-clés du certificat, l'authentification échouera et vous retrouverez
une erreur du type «
error: Certificate invalid: name is not a listed principal
» dans les journaux du système (auth.log
sous Debian), - si aucun nom-clé n'est présent dans le certificat, l'authentification va
échouer avec une erreur du type «
error: Certificate lacks principal list
» dans les journaux système (auth.log
sous Debian). (bien que ceci paraisse en contraction avec le manuel ssh-keygen(1) qui indique que « par défaut, les certificats générés sont valables pour tous les utilisateur⋅rice⋅s et tous les hôtes. ») ;
/chemin/vers/clef_utilisateur.pub
est l'argument qui désigne la clef publique de l'utilisateur⋅rice à laquelle correspondra le certificat.
Exemple de génération d'un certificat à partir de la clef publique
id_ed25519.pub
pour un⋅e utilisateur⋅rice (la phrase de passe demandée
ci-dessous est celle qui protège la clef privée ac_clients
) :
# ssh-keygen -s ac_clients -I "Herschel Krustofski" -n krusty id_ed25519.pub
Enter passphrase:
Signed user key id_ed25519-cert.pub: id "Herschel Krustofski" serial 0 valid forever
Le certificat créé par cette opération sera écrit dans le fichier
id_ed25519-cert.pub
du même répertoire que celui de la clef fournie en
argument (ici, il s'agit du répertoire courant).
Un certificat peut être examiné à l'aide de l'option -L
de ssh-keygen
:
$ ssh-keygen -L -f id_ed25519-cert.pub
id_ed25519-cert.pub:
Type: ssh-ed25519-cert-v01@openssh.com user certificate
Public key: ED25519-CERT SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE
Signing CA: ED25519 SHA256:iuqKv2w9iXf+Cj3+0+/EqPxghEYAbWJQuReDkZXtBYs (using ssh-ed25519)
Key ID: "Herschel Krustofski"
Serial: 0
Valid: forever
Principals:
krusty
Critical Options: (none)
Extensions:
permit-X11-forwarding
permit-agent-forwarding
permit-port-forwarding
permit-pty
permit-user-rc
Utilisation d'un certificat client
Côté serveur SSH
Pour que le serveur SSH reconnaisse la validité des signatures dans les
certificats présentés par les clients SSH qui se connectent à lui, il doit
disposer de la clef publique du certificat qui a servi à les générer (dans
notre exemple, il s'agit donc de la clef conservée dans le fichier
ac_clients.pub
).
Cette clef doit figurer dans un fichier qui doit être référencé dans le fichier
de configuration du serveur SSH (/etc/ssh/sshd_config
sous les systèmes
Debian GNU/Linux), à l'aide de la directive TrustedUserCAKeys
:
TrustedUserCAKeys /etc/ssh/clefs_ac_clients
Ce fichier peut contenir plusieurs clefs ayant servi à générer des certificats clients. Nous pouvons y ajouter celle de notre exemple :
Le serveur SSH doit ensuite être redémarré pour tenir compte de cette nouvelle configuration :
Un certificat présenté par un client ne sera par défaut considéré que lorsque
sa liste de noms-clés (donnée par l'option -n
lors de sa génération) contient
le nom du compte auquel il tente de se connecter.
Il est cependant aussi possible d'accepter, pour chaque compte, une liste de noms-clés différents de ce nom de compte.
Il faut pour cela fournir un fichier spécifique à chaque compte qui sera
consulté pour trouver la liste des noms-clés acceptés pour ce compte. Ces
fichiers doivent être désignés à l'aide de la directive
AuthorizedPrincipalsFile
dans sshd_config
.
L'argument de cette directive peut utiliser %u
pour désigner l'identifiant du
compte, %U
pour l'uid du compte, et %h
pour son répertoire personnel. Par
exemple, pour utiliser un fichier pour chaque utilisateur⋅rice dans le
répertoire /etc/ssh/auth_principals
, on pourrait utiliser :
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
Au lieu d'utiliser un fichier, il est également possible de générer
dynamiquement une liste de noms-clés acceptés pour un compte à l'aide d'une
commande personnalisée qu'on devra désigner par une directive
AuthorizedPrincipalsCommand
et qui sera exécutée par l'utilisateur⋅rice
désigné⋅e par AuthorizedPrincipalsCommandUser
. Pour plus de détails,
réferrez-vous à la description de ces directives dans le manuel
sshd_config(5)
(en anglais).
Côté client
Côté client, l'utilisateur⋅rice doit fournir sa clef SSH publique,
id_ed25519.pub
dans notre exemple, à l'administrateur⋅rice du serveur et il
recevra en retour le certificat id_ed25519-cert.pub
généré à partir de
celle-ci et signé par l'autorité de certification client.
Elle ou il doit simplement placer ce fichier id_ed25519-cert.pub
dans le même
répertoire que le fichier id_ed25519
de sa clef SSH. Lors d'une connexion
utilisant cette clef id_ed25519
, le client SSH présentera alors
automatiquement le certificat au serveur.
On peut aussi constater que notre agent SSH local charge automatiquement le certificat lorsqu'on y ajoute la clef :
~$ ssh-add -l
The agent has no identities.
~$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/herschel/.ssh/id_ed25519:
Identity added: /home/herschel/.ssh/id_ed25519 (herschel@laptop)
Certificate added: /home/herschel/.ssh/id_ed25519-cert.pub (Herschel Krustofski)
~$ ssh-add -l
256 SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE herschel@laptop (ED25519)
256 SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE herschel@laptop (ED25519-CERT)
L'utilisateur⋅rice n'a donc pas besoin de changer sa configuration par rapport à l'utilisation de sa clef SSH seule. Il suffit de la mentionner comme d'habitude :
- avec l'option
-i
dessh
en ligne de commande, par exemple : - ou avec une directive
IdentityFile
dans son fichier de configuration client~/.ssh/config
(généralement dans une sectionHost
), par exemple :IdentityFile ~/.ssh/id_ed25519
En supposant que le fichier ~/.ssh/authorized_keys
du compte cible sur le
serveur auquel on se connecte en utilisant la clef SSH soit vide, on constate
que le serveur autorise malgré tout l'authentification par clef SSH grâce au
certificat :
$ ssh -i ~/.ssh/id_ed25519 lab.exemple.org
Linux lab 5.10.0-22-amd64 #1 SMP Debian 5.10.178-3 (2023-04-22) x86_64
Last login: Thu May 11 11:05:23 2023 from 192.168.1.42
~$
On peut vérifier l'utilisation du certificat avec l'option -v
du client ssh
lors de la connexion :
$ ssh -v -i ~/.ssh/id_ed25519 lab.exemple.org
...
debug1: Will attempt key: /home/herschel/.ssh/id_ed25519 ED25519 SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE explicit agent
debug1: Will attempt key: /home/herschel/.ssh/id_ed25519 ED25519-CERT SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE explicit agent
...
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering public key: /home/herschel/.ssh/id_ed25519 ED25519 SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE explicit agent
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: /home/herschel/.ssh/id_ed25519 ED25519-CERT SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE explicit agent
debug1: Server accepts key: /home/herschel/.ssh/id_ed25519 ED25519-CERT SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE explicit agent
debug1: Authentication succeeded (publickey).
...
Linux lab 5.10.0-22-amd64 #1 SMP Debian 5.10.178-3 (2023-04-22) x86_64
Last login: Thu May 11 11:05:23 2023 from 192.168.1.42
~$
On remarque dans ces lignes de debuggage fournie par ssh
que la clef SSH est
d'abord fournie au serveur sans certificat. Puisqu'elle n'a pas été autorisée
dans le fichier ~/.ssh/authorized_keys
du compte distant, l'authentification
échoue, et le client essaye à nouveau en présentant aussi le certificat, ce qui
débouche cette fois sur une authentification réussie.
Ceci montre que l'utilisation « habituelle » des clefs SSH basée sur
authorized_keys
reste possible en même temps que l'utilisation du certificat,
et qu'elle est tentée avant celle-ci par le client SSH.
Côté serveur, en cas de succès de l'authentification, on trouvera un message similaire à celui-ci dans les journaux système :
Accepted publickey for herschel from 192.168.1.42 port 40160 ssh2: ED25519-CERT SHA256:QfLKGkjku0mCMS9bTJPtuCkie3Cr158kb9C7axTYXRE ID Herschel Krustofski (serial 0) CA ED25519 SHA256:iuqKv2w9iXf+Cj3+0+/EqPxghEYAbWJQuReDkZXtBYs
Création d'un certificat serveur
Un certificat est généré pour un serveur en signant une de ses clefs publiques
à l'aide de la clef de l'autorité de certification (ac_serveurs
dans notre
exemple) :
Dans cette commande :
-s /chemin/vers/ac_serveurs
indique le chemin vers la clef privée représentant l'autorité de certification à utiliser pour les certificats serveurs ;-I id_clef
indique une identité qui peut être choisie librement et contenir des espaces (les caractères accentués ne sont toutefois pas correctement affichés). Elle sera mentionnée dans les informations émises par le client en mode verbeux (avec l'option-v
dessh
) lors de l'utilisation du certificat et peut être utilisée en cas de révocation du certificat si celui-ci n'a pas de numéro de série (voir l'article « Révoquer des clefs et certificats SSH ») ;-h
doit être utilisée pour générer des certificats pour serveurs, contrairement aux certificats pour clients (si cette option est oubliée, le client refusera le certificat avec l'erreur «Certificate invalid: not a host certificate
») ;-n nom1,nom2,…
précise un ou plusieurs noms-clés (principals en anglais) à inclure dans le certificat. Pour un certificat serveur, ces identifiants doivent être le ou les noms DNS du serveur pour lesquels le certificat doit être valide (séparés par une virgule). Si aucun nom-clé n'est précisé, les clients SSH vont accepter le certificat pour n'importe serveur (tant qu'il est issu d'une autorité de certification de confiance, bien sûr).
Exemple de génération d'un certificat à partir de la clef publique
ssh_host_ecdsa_key.pub
pour un serveur lab.example.org
(la phrase de passe
demandée est celle qui protège la clef privée ac_serveurs
) :
# ssh-keygen -s ac_serveurs -I "Serveur de test" -h -n lab.example.org,w1.example.org ssh_host_ecdsa_key.pub
Enter passphrase:
Signed host key ssh_host_ecdsa_key-cert.pub: id "Serveur de test" serial 0 for lab.example.org valid forever
Le certificat généré par cette opération sera écrit dans le fichier
ssh_host_ecdsa_key-cert.pub
du même répertoire que celui de la clef fournie en
argument (ici, il s'agit du répertoire courant).
Ce certificat peut là encore être vérifié à l'aide de la commande ssh-keygen -L
:
# ssh-keygen -L -f ssh_host_ecdsa_key-cert.pub
ssh_host_ecdsa_key-cert.pub:
Type: ecdsa-sha2-nistp256-cert-v01@openssh.com host certificate
Public key: ECDSA-CERT SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI
Signing CA: ED25519 SHA256:e7wnSbMmyStx4K0+Mk3dj/03m/bI4Fk823EL0WdD8l4 (using ssh-ed25519)
Key ID: "Serveur de test"
Serial: 0
Valid: forever
Principals:
lab.example.org
w1.example.org
Critical Options: (none)
Extensions: (none)
Utilisation du certificat serveur
Côté serveur SSH
Le certificat ainsi généré doit être référencé dans la configuration du serveur
SSH (son fichier sshd_config
) à l'aide d'une directive HostCertificate
:
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
Ce certificat doit correspondre à l'une des clefs désignées explicitement ou
implicitement (par ses valeurs par défaut) par une directive HostKey
. Dans
notre cas, le certificat correspond bien à la clef
/etc/ssh/ssh_host_ed25519_key
utilisée par défaut par le serveur SSH.
Comme après toute modification de la configuration du serveur SSH, celui-ci doit être redémarré pour tenir compte de sa nouvelle configuration :
Le serveur SSH propose aux clients qui se connectent des clefs d'hôte utilisant
différents types de clefs (chacun basé sur un algorithme différent), et le
client va choisir le type qu'il préfère utiliser selon une liste précisée dans
sa configuration (définie par la directive HostKeyAlgorithms
).
Notez que, par défaut, cette liste prend en compte les certificats avant toute clef. Cela signifie que la sélection des types de certificats par le client est indépendante de celle des types de clefs.
Côté client
Le client reçoit un certificat fourni par le serveur SSH lors de sa connexion. Il a alors besoin de la clef publique de l'autorité de certification ayant servi à l'établir pour pouvoir vérifier que la signature de la clef publique du serveur incluse dans le certificat a bien été réalisée par cette autorité.
Il est donc nécessaire de désigner au client la clef publique de l'autorité de
certification. Ceci doit être fait dans le fichier de configuration du client
SSH ~/.ssh/known_hosts
.
Cette désignation est effectuée à l'aide d'une ligne commençant par
@cert-authority
:
- un motif ou une liste de motifs séparés par des virgules doit être fourni en premier paramètre pour indiquer à quels serveurs s'applique cette clef d'autorité ;
- dans ces motifs,
*
correspond à une série de caractères, et?
à un caractère quelconque ; - le motif «
*
» utilisé seul indique que cette clef peut signer les certificats de n'importe quel serveur ; - le reste de la ligne fournit le type de clef et la clef encodée en base64.
Voici quelques exemples désignant des clefs d'autorités de certification :
@cert-authority * ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICSsDZABRKynUuiV5kyfDEgmwEgZ8a1pCsuRficEksDU Autorité de certification
@cert-authority *.sub.example.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICSsDZABRKynUuiV5kyfDEgmwEgZ8a1pCsuRficEksDU Autre autorité de certification
@cert-authority *.example.com,*.example.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICSsDZABRKynUuiV5kyfDEgmwEgZ8a1pCsuRficEksDU AC de Bidon SARL
Une fois la clef publique de l'autorité de certification précisée, le client pourra automatiquement authentifier les serveurs présentant un certificat qu'elle a créé.
L'utilisation du mot-clef @cert-authority
dans un fichier known_hosts
est
décrite dans la section SSH_KNOWN_HOSTS FILE FORMAT
du manuel
sshd(8)
(en anglais).
Cette section précise notamment que le client SSH compare le motif donné en
argument du mot-clef @cert-authority
avec :
- le nom du serveur tel qu'il a été fourni par l'utilisateur⋅rice ;
- ou le nom désigné par la directive
HostKeyAlias
si la connexion a été configurée dans le fichier~/.ssh/ssh_config
et qu'une telle directive a été utilisée ; - ou encore avec le nom canonique du serveur si la directive
CanonicalizeHostname
a été utilisée dans~/.ssh/ssh_config
.
L'option -v
de la commande ssh
permet de vérifier si nécessaire que le
certificat a bien été utilisé par le client SSH, et donne des informations
utiles si ce n'est pas le cas. Voici des exemples de messages affichés par
ssh
dans différents cas de figure :
- dans le cas positif où le nom du serveur auquel on cherche à se connecter
correspond bien au motif d'une ligne
@cert-authority
, que le certificat donné par le serveur comprend bien le nom complet du serveur dans ses noms-clés (ou qu'il n'a aucun nom-clé), et que la signature de la clef est valable, tout fonctionnera comme voulu et la commande affichera les messages suivants (avant de s'authentifier lui-même auprès du serveur) :~$ ssh -v lab.example.org OpenSSH_8.4p1 Debian-5+deb11u1, OpenSSL 1.1.1n 15 Mar 2022 ... debug1: Server host certificate: ecdsa-sha2-nistp256-cert-v01@openssh.com SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI, serial 0 ID "Serveur de test" CA ssh-ed25519 SHA256:e7wnS bMmyStx4K0+Mk3dj/03m/bI4Fk823EL0WdD8l4 valid forever debug1: Host 'lab.example.org' is known and matches the ECDSA-CERT host certificate. debug1: Found CA key in /home/herschel/.ssh/known_hosts:1 ... [suivent les messages relatifs à l'authentification de l'utilisateur⋅rice]
- dans le cas où aucun motif donné avec un mot-clef
@cert-authority
ne correspond au nom du serveur, ou que le certificat qui correspond n'a pas été établi par la clef d'autorité configurée, le message «No matching CA found
» sera indiqué et le client va utiliser la méthode habituelle de validation de la clef publique du serveur en la cherchant dans le fichierknown_hosts
et en proposant à l'utilisateur⋅rice de l'y ajouter si elle n'y est pas :~$ ssh -v lab.example.org ... debug1: Server host certificate: ecdsa-sha2-nistp256-cert-v01@openssh.com SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI, serial 0 ID "Serveur de test" CA ssh-ed25519 SHA256:e7wnS bMmyStx4K0+Mk3dj/03m/bI4Fk823EL0WdD8l4 valid forever debug1: No matching CA found. Retry with plain key The authenticity of host 'lab.example.org (192.168.1.3)' can't be established. ECDSA key fingerprint is SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI. Are you sure you want to continue connecting (yes/no/[fingerprint])?
- enfin, si le nom-clé du certificat est
example.org
et qu'on cherche à se connecter àlab.example.org
(ou tout autre nom ne figurant pas dans les noms-clés), on obtiendra en plus le message «Certificate invalid: name is not a listed principal
» (à moins que la liste de noms-clefs soit vide, auquel cas le client acceptera tout certificat valide) :~$ ssh -v lab.example.org ... debug1: Server host certificate: ecdsa-sha2-nistp256-cert-v01@openssh.com SHA256:wxocsORNEfXuuTcXGwitKR8RUompGbgpXTEsXXirAFI, serial 0 ID "Serveur de test" CA ssh-ed25519 SHA256:e7wnS bMmyStx4K0+Mk3dj/03m/bI4Fk823EL0WdD8l4 valid forever debug1: Host 'lab.example.org' is known and matches the ECDSA-CERT host certificate. debug1: Found CA key in /home/herschel/.ssh/known_hosts:1 Certificate invalid: name is not a listed principal debug1: No matching CA found. Retry with plain key ...
Options supplémentaires acceptées dans les certificats
Numéro de série
On a pu voir dans les exemples d'affichage de certificats (avec ssh-keygen -L
) ci-dessus que des options supplémentaires sont acceptées dans ces
certificats, en plus de celles décrites dans les sections précédentes.
Parmi celles-ci, un numéro de série (indiqué par Serial:
lors de l'affichage
des certificats) peut être précisé lors de la génération du certificat grâce à
l'option -z
de la commande ssh-keygen
. Il permettra de distinguer le
certificat des autres certificats générés par l'autorité de certification (ce
qui peut notamment être utile pour désigner un certificat dans une liste de
révocation de clefs – Key Revocation Lists, ou KRLs, décrits dans mon
article « Les listes de révocation de clefs sous
OpenSSH »).
Intervalle de validité
La validité (indiquée par Valid:
dans les affichages de certificats
plus haut) peut être précisée à l'aide de l'option -V
de ssh-keygen
. Si une
seule spécification de temps est fournie, alors le certificat sera valable
entre le moment présent et la date précisée. Si deux spécifications de temps
sont fournies, séparés par un deux-points :
, alors le certificat sera valable
uniquement dans cet intervalle.
Une spécification de temps peut être une date précisée au format YYYYMMDD
ou
YYYYMMDD-HHMM[SS]
, ou une date relative au temps présent, telles que décrites
à la section TIME FORMATS
du manuel
sshd_config(5)
(en anglais), par exemple « -15d
» pour 15 jours dans le passé, ou « +5w3d
»
pour 5 semaines et 3 jours dans le futur.
Le temps de départ peut aussi être always
pour indiquer que le certificat n'a
pas de date de début de validité, et celui de fin peut être forever
pour
indiquer que le certificat n'a pas de date d'expiration. Ces deux mots-clefs
représentent les valeurs par défaut si aucun interval de validité n'est
précisé.
Autres options
Des options supplémentaires peuvent être précisées avec l'option -O option
qui permettent de préciser des limitations d'utilisation du certificat selon
son usage. Référez-vous à la section CERTIFICATES
dans
ssh-keygen(1)
(en anglais) pour une description plus détaillée. Elles peuvent être utilisées
pour interdire le transfert de port, d'agent, d'écran, forcer une commande,
etc., comme on peut le faire avec les options des clefs
SSH
dans le fichier ~/.ssh/authorized_keys
.