TL;DR : l'algorithme ssh-rsa est désactivé dans la version de SSH livrée dans Ubuntu 22.04 car il utilise la fonction cryptographique SHA-1 qui est jugée dangereuse depuis des années.
Enfin, il ne faut pas confondre le format d'une clé SSH (RSA) et l'algorithme utilisé pour vérifier cette clé et signer avec (ssh-rsa = RSA + SHA-1). Ce n'est pas donc les clés RSA qui sont dépréciées par SSH et tu peux conserver la tienne (et celle de ton serveur) sans danger.
Un collègue met à jour sa station de travail à la version 22.04 d'Ubuntu. Il ne parvient plus à se connecter en SSH au serveur depuis lequel nous administrons nos serveurs (je refuse d'utiliser le terme « bastion », car il renvoie l'idée d'un point sécurisé, d'un contrôle d'accès fin, d'une journalisation des accès et des commandes saisies, etc. ce qui n'est pas le cas). L'erreur ? « Unable to negotiate with XXX.XXX.XXX.XXX port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ssh-ed25519 ».
Ubuntu 21.10 embarquait la version 8.4 d'OpenSSH (l'implémentation la plus répandue du protocole SSH). Ubuntu 22.04 embarque la version 8.9. (Source.) Or, à partir de sa version 8.8, OpenSSH désactive l'algorithme ssh-rsa. ssh-rsa = RSA + SHA-1. Or, ce dernier est considéré comme très faible depuis 2015, comme je l'ai évoqué dans un article sur le renforcement de mes configurations SSH.
Or, on constate que le serveur ne propose pas mieux que ssh-rsa (si l'on reste dans la famille RSA). Il ne propose pas rsa-sha2-256 ni rsa-sha2-512. C'est normal : il s'agit d'un système Debian 8 avec OpenSSH 6.7 ; les nouveaux algorithmes de la famille RSA sont implémentés à partir de la version 7.2 d'OpenSSH.
Tu vas me dire : « le serveur propose d'autres algorithmes, d'autres familles, le client l'annonce dans son message d'erreur, pourquoi ssh
ne bascule pas dessus automatiquement ? ».
En effet… Sur un Ubuntu 22.04, c'est l'algorithme ssh-ed25519 qui est choisi car il est pris en charge par le serveur (dernier choix) et qu'il est premier choix du client après les algorithmes qui utilisent des certificats (cf man ssh_config
).
Sur un Debian 10, c'est l'algorithme ecdsa-sha2-nistp256 qui est retenu, pour la même raison.
Sur un Ubuntu 22.04 avec un fichier known_hosts
contenant l'empreinte de la clé RSA du serveur SSH, ssh
affiche son traditionnel message « WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! » car il a négocié la présentation, par le serveur, de sa clé au format ED25519 (« The fingerprint for the ED25519 key sent by the remote host is »). Il suffit donc de supprimer l'empreinte de la clé de type RSA du fichier known_hosts
(la commande est donnée dans le message d'erreur) pour basculer sur l'algorithme ssh-ed25519 et ne plus avoir d'erreur.
Si mon collègue n'a pas eu ce message d'erreur, c'est probablement qu'il devait avoir une configuration de son client SSH qui autorisait uniquement les algorithmes de la famille RSA et, potentiellement, d'autres algorithmes non pris en charge par le serveur. Du coup, son client SSH ne pouvait pas utiliser la famille RSA à cause de la dépréciation de l'algorithme ssh-rsa, et il ne pouvait pas utiliser une autre famille d'algorithmes car on le lui interdit ou le serveur SSH ne les implémente pas.
Il y a plusieurs solutions :
Ré-autoriser l'utilisation de ssh-rsa dans la configuration SSH du client en ajoutant les lignes suivantes dans le fichier ~/.ssh/config
:
Host *
HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa
C'est la meilleure solution si t'as encore de vieux serveurs (< Debian 7) ou des swiths, car ils ne prennent pas en charge autre chose que ssh-rsa.
Utiliser un autre algorithme, donc un autre format de clé. Pour ce faire, il faut supprimer les empreintes de la clé RSA du serveur du fichier known_hosts
:
ssh-keygen -f ".ssh/known_hosts" -R "<nom_du_serveur>"
ssh-keygen -f ".ssh/known_hosts" -R "<adresse_IP_du_serveur>"
Oui, il faut cibler le nom et les adresses IP (si t'as IPv6 en sus d'IPv4, t'as une commande de plus à taper ;) ). Pour le nom, il s'agit du FQDN ou du seul nom de la machine en fonction de ton usage. Il faut s'assurer que le serveur prend en charge d'autres algorithmes (ssh -o 'HostkeyAlgorithms -ssh-rsa' <nom_du_serveur>
et que d'autres types de clés sont disponibles : ls -lh /etc/ssh/ssh_host_*
(si non, ça se génère avec ssh-keygen
, comme d'habitude).
Comme le dit le changelog d'OpenSSH : non, il est innocent.
Faut-il supprimer sa clé SSH RSA personnelle ? Non, elle est innocente.
Explications.
Lors de l'établissement d'une connexion SSH, une partie de l'échange se déroule ainsi :
/etc/ssh/ssh_host_*
sur le serveur. C'est cette clé dont tu dois valider l'empreinte lors de la première connexion à un serveur SSH (modèle de sécurité TOFU, Trust On First Use). Dans le cas de mon collègue, son client et le serveur décident que le serveur doit se présenter avec sa clé de type RSA (/etc/ssh/ssh_host_rsa_key*
) ;Sur un serveur plus récent (>= Debian 9), mon collègue ne rencontre aucun problème alors que le serveur se présente pourtant avec sa clé au format RSA, car ce serveur prend en charge des algorithmes RSA plus récents qui n'ont pas été dépréciés comme rsa-sha2-256 (RSA + SHA-256) et rsa-sha2-512.
Ce n'est donc pas le format de la clé (RSA) qui n'est plus pris en charge, mais l'algorithme de signature et de vérification car il repose sur la fonction cryptographique SHA-1 qui est considérée comme étant faible / dangereuse depuis des années.
Il est donc vain de jeter / changer / renouveler sa clé SSH personnelle au format RSA à coup de ssh-keygen
, car le sujet est la clé du serveur.
Et il est démesuré de jeter la clé SSH RSA du serveur, car le sujet est l'algorithme utilisé, pas le format de la clé.
Ha, au fait, j'ai simplifié ci-dessus : la négociation du format de la clé et de l'algorithme se fait en une seule et même étape. Je l'ai découpé en deux afin de bien appuyer sur la différence entre le format de la clé et les procédures de signature et de vérification cryptographiques effectuées avec cette clé.