Sans clés signées, on doit distribuer sa clé publique à tous les users distants qui vont chacun·e l'intégrer dans son ~/.ssh/authorized_keys
. Si nous décidons de changer de clé, il faut re-distribuer sa nouvelle clé partout où cela est nécessaire. Enfin lors de la 1ère connexion à un serveur, celui-ci nous envoie sa clé que nous devons accepter car non connue. De la même manière, si cette clé change ou si nous nous y connectons en utilisant un nom différent, il faudra à nouveau accepter la clé.
La clé user envoyée peut être soumise à des restrictions précisées dans ~/.ssh/authorized_keys
, par exemple no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding
.
Avec des certificats (signature de la clé), seule la clé publique de l'autorité qui signe les clés des users doit être communiquée aux différents serveurs. De la même manière, seule la clé publique de l'autorité qui signe les clés des serveurs doit être communiquée globalement aux clients. Toutes les clés signées par ces autorités seront acceptées (à certaines conditions). Ainsi il est possible de changer sa clé user ou du serveur sans avoir à la communiquer. Il suffit juste de la signer.
Les restrictions citées ci-dessus sont intégrées dans le certificat. Un certificat peut aussi avoir une date de validité et un numéro de série.
Les fichiers ~/.ssh/authorized_keys
et ~/.ssh/known_hosts
deviennent inutiles et peuvent être supprimés… une fois que vous avez vérifié·es le bon fonctionnement de vos serveurs ssh.
Clé que l'on utilisera pour signer la clé du serveur sshd :
ssh-keygen -t ed25519 -f host_ca -C "Host Certificate Authority"
Clé qui signera les clés des users autorisé·es à se connecter au serveur :
ssh-keygen -t ed25519 -f user_ca -C "User Certificate Authority"
Clé du serveur sshd :
ssh-keygen -f ssh_host_ed25519_key -N '' -t ed25519
Clé d'un user :
ssh-keygen -t ed25519
Signature de la clé du serveur sshd :
ssh-keygen -s host_ca -I <hostservername> -h -n <hostservername> -V '+52w' -z 0001 ssh_host_ed25519_key.pub
myhost.example.org,myhost
”.Signature de la clé d'un user :
ssh-keygen -s user_ca -I <user@hostname> -n user1,user2,user3 -V '+52w' -z 0001 id_ed25519.pub
Il est possible d'ajouter des options :
-O no-agent-forwarding -O no-port-forwarding -O no-pty -O no-user-rc -O no-X11-forwarding
ssh-keygen -Lf id_ed25519-cert.pub id_ed25519-cert.pub: Type: ssh-ed25519-cert-v01@openssh.com user certificate Public key: ED25519-CERT SHA256:UAsTjJVR6X5Os9jl8u9ERWyrXM16Emi4P4wzDSyd9m7 Signing CA: ED25519 SHA256:PuFWoaE75fHFOz+RVxHXpAVRfqv1WX9J7UaDwAMaKBH (using ssh-ed25519) Key ID: "user1@mydomain.com" Serial: 1 Valid: from 2024-04-17T08:13:00 to 2025-04-16T08:14:43 Principals: user1 user2 user3 Critical Options: (none) Extensions: permit-X11-forwarding permit-agent-forwarding permit-port-forwarding permit-pty permit-user-rc
Sur chaque serveur, copiez la clé publique du certificat user :
# install -m 644 user_ca.pub /etc/ssh/ssh_user_ca.pub
Ajoutez ces lignes dans /etc/ssh/sshd_config
:
HostKey /etc/ssh/ssh_host_ed25519_key HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub TrustedUserCAKeys /etc/ssh/ssh_user_ca.pub
Puis redémarrez le serveur sshd.
Sur chaque client, peuplez le fichier known_hosts
:
# echo "@cert-authority * <contenu de host_ca.pub>" > /etc/ssh/ssh_known_hosts
J'aurais pu mettre *.domain.tld
pour dire que cette clé n'est utile que pour ces domaines.
Ajoutez ces lignes dans /etc/ssh/ssh_config
:
Host * IdentityFile ~/.ssh/id_ed25519 CertificateFile ~/.ssh/id_ed25519-cert.pub
Dorénavant vous n'aurez plus jamais besoin des fichiers ~/.ssh/known_hosts
et ~/.ssh/authorized_keys
. En effet, le fichier /etc/ssh/ssh_known_hosts
contient la clé publique de l'autorité qui signe les clés des serveurs sshd. Lors d'une 1ère connexion à un serveur, il ne vous sera plus demandée d'accepter (aveuglément) la clé du serveur.
Le fichier /etc/ssh/ssh_user_ca.pub
vérifie que le certificat envoyé est bien valide avec les options et les users autorisés, ce qui rend osbolète ~/.ssh/authorized_keys
.
Merci aux auteurs de ces articles :