Clés SSH et certificats

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.

Création des autorités

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"
On ne va créer qu'une seule fois ces autorités pour tous les serveurs sshd et tous les users.
Conserver les clés privées de ces autorités en lieu sûr. Et surtout assurez-vous que vous pouvez les utiliser localement.
Si vous les stocker à distance et que vous ne pouvez plus accéder au serveur en question car votre certificat a expiré, vous serez dans le… Personnellement je stocke mes clés dans mon fichier keepass.

Génération des clés

Clé du serveur sshd :

ssh-keygen -f ssh_host_ed25519_key -N '' -t ed25519

Clé d'un user :

ssh-keygen -t ed25519

Signature des clés

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
  • -s host_ca : on signe avec cette clé.
  • -h : on signe la clé d'un hostname et non d'un user.
  • -I <hostservername> : c'est le nom que l'on verra dans les logs, je préfère que l'on voit le nom du hostname mais on peut mettre n'importe quoi.
  • -n <hostservername> : ce sont les noms autorisés pour se connecter au serveur, on peut mettre plusieurs noms séparés par une virgule. Exemple : “myhost.example.org,myhost”.
  • -V '+52w' : le certificat sera valide 52 semaines. Sans cette option, le certificat n'expire pas.
  • -z 0001 : numéro de série du certificat (facultatif). Il permet de vérifier si un certificat obsolète est utilisé.

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
  • -s user_ca : on signe avec cette clé.
  • -I <user@hostname> : c'est le nom que l'on verra dans les logs, je préfère que l'on voit le nom complet de l'user mais on peut mettre n'importe quoi.
  • -n user1,user2,user3 : c'est la liste des users autorisés auxquels on peut se connecter sur le serveur.

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

Vérifier le certificat

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

Intégrer l'autorité des clés users sur les serveurs

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.

Intégrer l'autorité des clés serveurs sur les clients

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 :

tuto/ssh-certificat.txt · Dernière modification : 2024/04/29 10:01 de Thomas
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0