L'utilisation de certificats permet de garantir l'identité du client et du serveur. OpenSSH permet de gérer des certificat dans un format spécifique. Ce ne sont pas des certificats x509.
OpenSSH gère des certificats dans un format spécifique qui ne sont pas des certificats x509 utilisables avec SSL/TLS.
La clé publique des utilisateurs et des serveurs doit être signée par la clé privée d'une autorité de certification spécifique à OpenSSH.
Le fichier de configuration du service SSH est /etc/ssh/sshd_config.
Lors de l'installation du serveur SSH ses clés privées et publiques sont générées sous plusieurs formats dans le dossier /etc/ssh, pour garder une comptabilité avec des clients plus anciens :
Dans le fichier de configuration du service SSH /etc/ssh/sshd_config, il est possible de fixer le type de clé côté serveur avec la directive HostKey.
Exemple :
HostKey /etc/ssh/ssh_host_rsa_key
La vérification de la configuration du service SSH se fait avec la commande suivante :
# /usr/sbin/sshd -d
ssh-keygen permet de générer un paire de clés privée / publique pour gérer la CA OpenSSH. Les clés seront enregistrées dans le dossier /etc/ssh accessible uniquement avec les droits root.
Création en précisant :
Création de la paire de clé de type ecdsa pour la CA OpenSSH dans le dossier /etc/ssh :
ssh-keygen -f /etc/ssh/ssh_ca -C "CA for SSH" -N "Sio1234*"
Une clé publique SSH est une chaîne de texte en une seule ligne, avec plusieurs parties distinctes : <type> <clé encodée en base64> <commentaire facultatif>
Type : Spécifie l'algorithme utilisé pour générer la clé. Par exemple :
Clé encodée en base64 : chaîne encodée en Base64 représentant la clé publique.
Commentaire facultatif : information pour identifier la clé : nom d'utilisateur et l'hôte depuis lequel la clé a été générée.
La clé privée de la CA (/etc/ssh/ssh_ca) va signer la clé publique du serveur (clé générée automatiquement lors de l'installation du service SSH). Pour cet exemple c'est la clé ecdsa qui sera signée.
Utilisation des paramètres suivants :
$ ssh-keygen -s /etc/ssh/ssh\_ca -I SSH-SERVEUR1-CERT \ -h -z 1234 \ -n localhost,10.0.0.102,www.serveurweb.fr \ /etc/ssh/ssh\_host\_ecdsa\_key.pub
Le certificat Serveur /etc/ssh/ssh_host_ecdsa_key-cert.pub a été créé.
Le paramètre -L permet d'afficher le contenu du certificat :
ssh-keygen -L -f /etc/ssh/ssh\_host\_ecdsa\_key-cert.pub /etc/ssh/ssh_host_ecdsa_key-cert.pub: Type: ecdsa-sha2-nistp256-cert-v01@openssh.com host certificate Public key: ECDSA-CERT SHA256:gncg0I1AzJaivFQL5mA7V2H/5c8CSY4kZEdyuCK6ySQ Signing CA: ECDSA SHA256:t225t0te+LcQXCo1og6TYAnD2PIQ/vnMo/nWL64bIaY (using ecdsa-sha2-nistp256) Key ID: "SSH-SERVEUR1-CERT" Serial: 1234 Valid: forever Principals: localhost 10.0.0.102 www.serveurweb.fr Critical Options: (none) Extensions: (none)
Commentaires :
Le serveur doit être configuré pour présenter ce certificat à tout client qui voudra se connecter.
Pour cela modifier le fichier du service SSH /etc/ssh/sshd_config pour
# utiliser un certificat serveur HostKey /etc/ssh/ssh_host_ecdsa_key HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
Le lancement en mode debug du service ssh montre le chargement de la clé privée et du certificat :
root@Serveur1:~# /usr/sbin/sshd -d ... debug1: private host key #0: ecdsa-sha2-nistp256 SHA256:gncg0I1AzJaivFQL5mA7V2H/5c8CSY4kZEdyuCK6ySQ debug1: host certificate: #0 type 6 ECDSA-CERT ...
Redémarre le service SSH sur le serveur
systemctl restart ssh
Il est maintenant possible pour un client SSH de se connecter à un serveur présentant un certificat signé par la CA :
Pour indiquer qu'un serveur particulier, présentant un certificat sign par la CA OpenSSH n'est plus de confiance, il suffit d'ajouter dans le fichier known_hosts une ligne avec le marqueur @revoked associé à la clé publique du serveur.
La configuration du client permet à celui-ci de faire confiance à n'importe quel serveur qui présente un certificat signé par une CA préalablement définie.
Pour cela, le fichier ~/.ssh/known_hosts doit contenir une ligne avec la directive @cert-authority et la clé publique de la CA qui est reconnue.
Le format d'une ligne est le suivant avec des quatre types d'information séparés par des espaces :
Récupérez la clé publique de la CA et ajoutez-là dans le fichier know_hosts puis compétez la ligne ajoutée pour ajouter les paramètres nécessaires (directive @cert-authority, hostnames). Cela devfraot resmebler à cela :
@cert-authority 10.* ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPsbCPdkmh9SXN2b/WwU9dqQi7z+0W5YY3SblMHdIS7gkQ2/YcFfCs/f56cwIDc2pkNmuVoFDJPo2gg5khqYtDg= CA for SSH
En se connectant en mode verbeux, vous visualisez que le certifivatt présenté a bien été validé :
debug1: Server host certificate: ecdsa-sha2-nistp256-cert-v01@openssh.com SHA256:gncg0I1AzJaivFQL5mA7V2H/5c8CSY4kZEdyuCK6ySQ, serial 1234 ID "SSH-SERVEUR1-CERT" CA ecdsa-sha2-nistp256 SHA256:t225t0te+LcQXCo1og6TYAnD2PIQ/vnMo/nWL64bIaY valid forever debug1: load_hostkeys: fopen /home/charles/.ssh/known_hosts2: No such file or directory debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts: No such file or directory debug1: load_hostkeys: fopen /etc/ssh/ssh_known_hosts2: No such file or directory debug1: Host '10.0.0.102' is known and matches the ECDSA-CERT host certificate. debug1: Found CA key in /home/charles/.ssh/known_hosts:1
$ ssh-keygen -s id_rsa -I charles-CERT id
Le paramètre -L permet d'afficher le contenu du certificat :
ssh-keygen -L -f id_rsa-cert.pub id_rsa-cert.pub: Type: ssh-rsa-cert-v01@openssh.com user certificate Public key: RSA-CERT SHA256:Dv79U+oPIbv5CGIiROMxM02479DZwaj3xOcYJKw1Bww Signing CA: RSA SHA256:Dv79U+oPIbv5CGIiROMxM02479DZwaj3xOcYJKw1Bww (using rsa-sha2-512) Key ID: "charles" Serial: 0 Valid: forever Principals: (none) Critical Options: (none) Extensions: permit-X11-forwarding permit-agent-forwarding permit-port-forwarding permit-pty permit-user-rc
Commentaires :
Les certificats OpenSSH permettent d'ajouter :
Pour signer un certificat avec ssh-keygen, deux paramètres au minimum sont nécessaires :
Il est cependant indispensable de préciser :
Le nom du fichier de certificat est généré en ajoutant -cert.pub au nom de la clé publique. Sur le serveur ayant les clé de la CA OpenSSH, signez la clé publique de l'utilisateur :
ssh-keygen -s /etc/ssh/ssh_ca -I CHARLES-CERT \ -z 1 -n charles id_rsa.pub
Le paramètre -L permet d'afficher le contenu du certificat :
ssh-keygen -L -f /home/charles/id_ecdsa-cert.pub /home/charles/id_ecdsa-cert.pub: Type: ecdsa-sha2-nistp256-cert-v01@openssh.com user certificate Public key: ECDSA-CERT SHA256:vq5uCGtqvFGK2CiBX07gtXvfZuGklvnrQ2IBqEoiuzA Signing CA: ECDSA SHA256:t225t0te+LcQXCo1og6TYAnD2PIQ/vnMo/nWL64bIaY (using ecdsa-sha2-nistp256) Key ID: "CHARLES-CERT" Serial: 1 Valid: forever Principals: charles Critical Options: (none) Extensions: permit-X11-forwarding permit-agent-forwarding permit-port-forwarding permit-pty permit-user-rc
Commentaires :
Il y a plusieurs méthodes :
Pour activer la validation généralisée des certificats, le fichier de configuration du serveur SSH /etc/ssh/sshd_config doit contenir la directive TrustedUserCAKeys qui précise le nom du fichier contenant la liste des clef publique des CA OpenSSH.
TrustedUserCAKeys /etc/ssh/ssh_ca_keys
IMPORTANT : le certificat du client ne sera considéré que si sa liste de nom-clés (principal) contient le nom du compte auquel il tente de se connecter.
SAUF si un fichier spécifique à chaque compte indique la liste des noms-clés acceptés. Directive AuthorizedPrincipalsFile dans sshd_config
L'utilisateur peut maintenant se connecter en SSH au serveur sans avoir au préalable fait renseigner sa clé publique dans le fichier authorized_keys du serveur
Au niveau du serveur SSH, la révocation de clés publiques se fait à l'aide de la directive RevokedKeys en précisantle nom du fichier global contenant la liste des clés qui doivent être refusées. Cela fonctionne pour toutes les clés publiques, même s'il n'y a pas de certificat associé à la clé.
TrustedUserCAKeys /etc/ssh/ssh_ca_keys RevokedKeys /etc/ssh/ssh_revoked_keys
Sur le serveur SSH, l'accès à un autre compte utilisateur que ceux listés dans les principals de son certificat est possible en utilisant la directive AuthorizedPrincipalsFile dans le fichier de configuration du serveur SSH /etc/ssh/sshd_config :
AuthorizedPrincipalsFile .ssh/authorized_principals
Dans ce cas-là, le serveur vérifie qu'un nom de la liste des principals du certificat qu'on lui propose apparaît bien dans le fichier .ssh/authorized_principals du compte cible.
Depuis le paragraphe 5.1, le certificat de l'utilisateur cb contientles valeurs cb , borelly et root . Il suffit donc d'indiquer une de ces 3 valeurs dans le fichier authorizedprincipals ducompte auquel on désire accéder. Le mode debug du serveur SSH nous indique que ce fichier est maintenant bien analysé en premier lieu quand l'utilisateur cb tente de se connecter sur le compte de root avec ce certificat : root@pccb ~# echo borelly > /root/.ssh/authorizedprincipals root@pccb ~# /usr/sbin/sshd -d … Failed publickey
Quand un client accepte pour la première fois la connexion à un serveur, il enregistre dans le fichier ~/.ssh/know_hosts une ligne avec la clé publique du serveur.
Lors d'une prochaine connexion, la clé présentée par le serveur sera comparée à celle déjà enregistrée afin d'éviter les attaques du type homme du milieu.
Le client gère la liste des serveurs connus dans son fichier ~/.ssh/hnow_hosts :
ssh-keygen -F @IP
Le client doit faire signer sa clé publique pour obtenir un certificat qui doit être placé dans le même répertoire que sa clé privé et publique.
cp client_key ~/.ssh/ cp client_cert.pub ~/.ssh/
Les permissions doivent être correctes :
chmod 600 ~/.ssh/client_key chmod 644 ~/.ssh/client_cert.pub
Lors d’une connexion avec la clé privée, le certificat sera automatiquement présenté au serveur.
Le client ssh doit seulement indique quelle clé privée utiliser avec l’option -i
ssh -i ~/.ssh/client_key nomDNSserveur
Ainsi même s’il n’y a pas de clé publique client dans authorized_keys, l’authentification se fait. L’option -v permet de voir l’utilisation du certificat
ssh -v -i ~/.ssh/client_key nomDNSserveur
Vous pouvez utiliser aussi le fichier de configuration du client ssh
Host <nom_du_serveur> HostName <adresse_du_serveur> User <nom_utilisateur> IdentityFile ~/.ssh/client_key CertificateFile ~/.ssh/client_cert.pub
$ ssh-keygen -y -f utilisateur-identite.pem > id_rsa.pub
$ openssl x509 -in charles-cert.pem -pubkey –noout > id_rsa.pem
noout permet d’avoir uniquement la clé publique sans le certificat
$ ssh-keygen -i -m PKCS8 -f id_rsa.pem > id_rsa.pub
$ openssl x509 -in pkicub-cert.pem -pubkey –noout > ca.pem
* Convertir la clé publique du format PEM au format openssh
$ ssh-keygen -f ca.pem > ca.pub
journalctl -u ssh
ssh -v <nom_du_serveur>
echo "@cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQE..." >> ~/.ssh/known_hosts
Cela permet au client de faire confiance à tous les serveurs avec des certificats signés par cette CA.
openssl x509 -in filename.pem -text –noout
-noout pour ne pas afficher en base64 qui permet d’encode des données binaires ASCII
openssl x509 -in filename.pem -issuer –noout
openssl x509 -in filename.pem -subject –noout
openssl x509 -in filename.pem -fingerprint –noout
openssl x509 -in filename.pem –pubkey -noout –out id_rsa.pub
Configurer une authentification SSH avec des certificats (et non simplement des clés publiques/privées) est une méthode avancée qui repose sur un serveur d'autorité de certification (CA) pour signer les clés SSH. Voici un guide étape par étape pour mettre cela en place :
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_cert
Cela crée :
2. Créer une autorité de certification (CA) Sur la machine administrateur (ou serveur CA) :
ssh-keygen -f /etc/ssh/ssh_ca -C "CA for SSH" -N ""
Cela crée :
3. Signer la clé publique de l'utilisateur Toujours sur la machine CA :
ssh-keygen -s /etc/ssh/ssh_ca -I user_cert -n nom_utilisateur -V +52w ~/.ssh/id_rsa_cert.pub
Cela génère un fichier idrsacert-cert.pub.
Visualiser le contenu du certificat :
ssh-keygen -L -f id_rsa_cert.pub
TrustedUserCAKeys /etc/ssh/ssh_ca.pub
Puis redémarrez le service SSH :
sudo systemctl restart sshd
Host monserveur HostName monserveur.exemple.com User nom_utilisateur IdentityFile ~/.ssh/id_rsa_cert CertificateFile ~/.ssh/id_rsa_cert-cert.pub
ssh monserveur
Script Bash automatisé pour configurer une authentification SSH avec des certificats :
Ce que fait le script :
Utilisation :
chmod +x configurer_authentification_ssh.sh
s # À exécuter avec les droits root ou sudo
echo “[1/5] Génération de la paire de clés utilisateur…” USERKEYDIR=“$HOME/.ssh” USERKEYNAME=“idrsacert” mkdir -p “$USERKEYDIR” ssh-keygen -t rsa -b 4096 -f “$USERKEYDIR/$USERKEYNAME” -N “”
echo “[2/5] Création de l'autorité de certification…” CADIR=“/etc/ssh” CAKEYNAME=“sshca” sudo ssh-keygen -f “$CADIR/$CAKEY_NAME” -C “CA for SSH” -N “”
echo “[3/5] Signature de la clé publique utilisateur…” CERTID=“usercert” USERNAME=“$(whoami)” VALIDITY=“+52w” sudo ssh-keygen -s “$CADIR/$CAKEYNAME” -I “$CERTID” -n “$USERNAME” -V “$VALIDITY” “$USERKEYDIR/$USERKEYNAME.pub”
echo “[4/5] Configuration du serveur SSH…” sudo bash -c “echo 'TrustedUserCAKeys $CADIR/$CAKEYNAME.pub' » /etc/ssh/sshdconfig” sudo systemctl restart sshd
echo “[5/5] Création du fichier de configuration SSH client…” CONFIGFILE=“$USERKEYDIR/config” SERVERALIAS=“monserveur” SERVER_HOST=“monserveur.exemple.com”
cat «EOF
> "$CONFIG_FILE"
H
ost $SERVERALIAS HostName $SERVERHOST
User $USERNAME IdentityFile $USER_KEY_DIR/$USER_KEY_NAME CertificateFile $USER_KEY_DIR/${USER_KEY_NAME}-cert.pub
EOF
chmod 600 “$CONFIG_FILE”
echo “ Configuration terminée. Vous pouvez maintenant vous connecter avec : ssh $SERVER_ALIAS”
</code>