===== 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 -h -n -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 : 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 : 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 -n user1,user2,user3 -V '+52w' -z 0001 id_ed25519.pub
* -s user_ca : on signe avec cette clé.
* -I : 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 * " > /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 :
* [[https://redwatch.io/blog/2023/certificats-ssh-utilisateur/|Pourquoi et comment utiliser un certificat SSH utilisateur]]
* [[https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Certificate-based_Authentication|OpenSSH/Cookbook/Certificate-based Authentication]]
* [[http://www.ixany.org/articles/presentation-and-use-of-ssh-certificates/|Presentation and use of SSH certificates]]