Contenu

Sécuriser son accès SSH 🖥️ avec une clef FIDO2 🔐

FIDO2 U2F

Une clef FIDO2 (Fast Identity Online) est une clef matérielle respectant le dernier ensemble de spécifications de la FIDO Alliance. Cet ensemble de spécifications FIDO2 est composé :

  • du protocole WebAuthN permettant une authentification forte de l’utilisateur sur un site web
  • du protocole CTAP, la couche de bas niveau sur laquelle s’appuie WebAuthN

L’usage d’une clef matérielle renforce la sécurité sur internet et permet de sécuriser les accès Web et applicatifs.

Dans cet article, nous allons nous intéresser à une méthode permettant d’utiliser ce type de clef pour nous connecter à un serveur SSH distant, en garantissant un haut niveau de sécurité tout en assurant une facilité d’utilisation sans mot de passe 😎, ce qui permet, à nous humains, de se décharger de la mémorisation d’un nième mot de passe !

Pourquoi utiliser une clef pour l’accès SSH ?

Tout d’abord, l’usage d’une paire de clef cryptographique asymétrique pour l’accès SSH est recommandé par l’ANSSI avec un chiffrement par ordre de préférence :

  • par cryptographie asymétrique ECDSA
  • par cryptographie asymétrique RSA
  • par cryptographie symétrique
  • par l’utilisation d’un module tiers, PAM / BSD Auth …
  • par mot de passe

📝 Dans tous les cas, si l’utilisateur a des privilèges élevés sur le système, l’usage du mot de passe est à proscrire 1

Habituellement, nous utilisons un fichier de clef privée dont le chiffrement est basé sur ed25519 et enregistré sous ~/.ssh/id_ed25519.

L’ ANSSI recommande l’usage de la méthode cryptographique ECDSA, mais cette dernière est sujette à des controverses d’ordre politiques et techniques, nous utiliserons dans cet article la méthode de chiffrement ed25519 qui est communément admise comme étant la plus sûre actuellement et compatible avec la clef U2F 2.

Une passphrase ? la flemme

Malgré l’usage d’une clef SSH, il est préconisé d’appliquer une passphrase pour sécuriser ce fichier secret, malheureusement, l’usage devient alors plus contraignant s’il est nécessaire de taper la phassphrase pour chaque connexion aux serveurs ssh distants. Même si les distributions GNU/Linux actuelles fournissent un trousseau de clefs qui conserve en mémoire les clefs privées déverouillées, cela nécessite de mémoriser une passphrase complexe pour sécuriser le fichier de la clef privée sur le disque.

La Yubikey

Plusieurs clefs matérielles implémentant le standard FIDO2 sont proposées sur le marché par divers constructeurs, voici quelques marques reconnues :

  • Yubico - les clefs Yubikey sont les plus connues
  • SoloKeys - la clef Solo Tap est la seule ayant un hardware et firmware totalement Open-Source
  • Feitian - fournisseur de produits Fido variés
  • Kensington - La clef Verimark permet également une authentification Windows Hello par empreinte digitale
  • Google - Ayant participé au développement FIDO2, son jeu de clefs Titan prend en charge NFC, USB-A et USB-C
  • Neowave - Entreprise 🇫🇷 qui commercialise la Winkeo Fido2, certifiée par l’ANSSI et labellisée Cybersecurity Made in Europe

Chez MaxDS, nous recevons une 🔑 Yubikey 5 dès notre arrivée dans l’entreprise 😎, c’est pourquoi, nous allons nous intéresser dans cet article à son usage avec OpenSSH. Les autres clefs FIDO2 devraient fonctionner également, mais il faut se rapprocher du constructeur pour y trouver les informations nécessaires.

Cette clef contient 6 différents protocoles en deuxième facteur d’authentification :

  • OTP
  • FIDO U2F
  • FIDO2
  • OATH
  • PIV / Smart card
  • OpenPGP

Sans entrer dans le détail de chaque protocole, nous nous intéresserons uniquement à la spécificité FIDO2 dans cet article.

Pré-requis

  • 🌍 Sur le serveur distant, installer une version du serveur OpenSSH dans une version >= 8.2. La prise en charge des clefs matérielles est effective à partir de cette version.3
    1
    2
    
      sudo apt install openssh-server
      sshd --version
    
  • 💻 Vous devez disposer également d’une version minimum 8.2 d’OpenSSH sur votre pc.
  • 💻 Sur votre poste local, installer l’utilitaire ykman en suivant ce guide
    ou suivre l’installation simplifiée sous Debian/Ubuntu ci-dessous
    1
    2
    3
    
    sudo apt-add-repository ppa:yubico/stable
    sudo apt update
    sudo apt install yubikey-manager
    

📔 Si besoin, vous trouverez une documentation complète de cet utilitaire en ligne de commande ici.

Initialisation de la Yubikey

  • 💻 Vérifier en premier lieu la reconnaissance de la Yubikey

    1
    
    ykman fido credentials list
    

    Cette commande doit retourner la liste des clefs Fido2 contenue dans votre Yubikey.

  • 💻 Code PIN (optionel) Si vous obtenez l’erreur suivante Error: Credential Management requires having a PIN. Set a PIN first, c’est que vous n’avez jamais enregistré de code PIN sur la clef, vous pouvez le faire avec la commande suivante

    1
    
    ykman fido access change-pin
    

    💡 Le code PIN n’est pas restreint aux chiffres, il peut contenir des lettres et caractères spéciaux.

🗒 Une Yubikey peut être utilisé sur un nombre illimité de sites en WebAuthN, mais dans une optique d’usage en “loginless/passwordless”, il est également possible d’enregistrer le login complet pour éviter de les renseigner lors de la saisie. C’est une possibilité offerte par le protocole WebAuthN (par exemple sur outlook), il est possible d’enregistrer jusqu’à 25 credentials de ce type sur une Yubikey 5. Cette limite ne représente pas une réelle contrainte, car il est toujours possible d’utiliser le WebAuthN en illimité.

Deux types de clefs possibles

Pour créer notre première clef SSH dans la Yubikey, il faut tout d’abord faire un choix, la 💊 rouge, ou la 💊 bleue, Suivons le lapin blanc 🐰 pour distinguer les deux types.

Une clef résidente

La clef au format resident est stockée uniquement dans la Yubikey, Ce type est recommandé si vous souhaitez pouvoir vous connecter depuis n’importe quel PC, la seule détention de la Yubikey permettra de se connecter à notre serveur SSH distant.

Une clef partagée

Une clef partagée est composée de la Yubikey et d’un fichier stocké sur l’ordinateur.
Ce fichier seul, ne permet pas l’authentification auprès d’un serveur SSH, il est considéré comme une clef privée enregistrée dans le répertoire ~/.ssh/ mais protégée par une passphrase, qui sera dans ce cas la Yubikey (c’est une analogie, cela ne fonctionne pas exactement de cette façon).
De même, la seule possession de la Yubikey ne sera pas suffisante pour s’authentifier auprès de notre serveur SSH distant.
Ce mode de connexion est le plus sécurisé, mais plus restrictif, car il nécessite d’avoir les 2 éléments, et cela peut devenir problématique sur un nouveau PC par exemple.

Génération de la clef résidente

🗒 Nous utiliserons la méthode de clef résidente dans cet article, car elle est suffisamment sécurisée et plus pratique à l’usage.

💻 Pour générer une clef de type resident, taper la commande suivante

1
ssh-keygen -t ed25519-sk -O "resident" -O "application=ssh:principal" -N "" -f ~/.ssh/yubikey_principale
Suite à cette commande, l’utilitaire vous demandera le code PIN, et n’oubliez pas de valider en appuyant sur la touche de Yubikey.

  • -t ed25519-sk indique le format de clef basée sur les courbes elliptiques ed25519
  • -O resident cette option permet de choisir le type de clef
  • -f ~/.ssh/yubikey_principale définit le fichier descriptif associé à la clef résidente
  • -O application=ssh:<nom_application> il est possible d’enregistrer jusqu’à 25 clefs résidentes dans la clef physique. Cette option permet de nommer chacune d’entre elle.
  • -N "" définit une passphrase vide, devenue inutile, car la clef privée reste dans la Yubikey

⚠️ Attention si vous ne définissez pas l’option application=ssh:<nom_application> vous allez créer une clef qui aura simplement le nom ssh: et vous risquez d’écraser par mégarde votre clef résidente si vous réexécuter la commande sans préciser le nom de l’application. Il est donc conseillé d’utiliser toujours un nom d’application qui fait sens.
exemples : ssh:gitlab, ssh:production, ssh:crypto

Vérifier la création de la clef avec la commande suivante

1
ykman fido credentials list

Vous devez voir désormais une clef ssh présente dans la Yubikey du type : ssh:principal 0000000000000000000000000000000000000000000000000000000000000000 openssh

Copie de votre clef publique sur le serveur distant

Une fois que vous avez généré la clef, l’utilisation est assez simple, commencez par copier le contenu de votre clef publique sur le serveur distant. Cette opération sera nécessaire une seule fois. Vous avez deux possibilités :

  • [Recommandé] Si vous disposez d’un accès distant au serveur (connexion ssh par password, fichier de clef existant, etc..), vous pouvez utiliser directement la commande suivante. Cela permet d’écrire votre clef publique dans le fichier ~/.ssh/authorized_keys de votre compte unix sur le serveur distant.
1
ssh-copy-id -i ~/.ssh/yubikey_principale -p 22 <utilisateur_distant>@<serveur_distant>
  • Si vous disposez d’un accès local au serveur, vous pouvez éditer le fichier ~/.ssh/authorized_keys (qui doit avoir les droits 600) directement sur le serveur, et y ajouter manuellement le contenu de votre clef publique ~/.ssh/yubikey_principale.pub.
    Ce contenu doit commencer par sk-ssh-ed25519@openssh.com AAAA....

🎉 Utilisation de la clef

Connexion ssh

Enfin nous y voilà, l’usage simplifié des connexions SSH, le graal de la sécurité et aussi user-friendly qu’un décapsuleur mural 😁

1
ssh -i ~/.ssh/yubikey_principale <utilisateur_distant>@<serveur_distant>

Appuyer sur le bouton tactile de la Yubikey et vous êtes connecté sans taper de mot de passe 🎉

Pour rendre l’usage encore plus simple, vous pouvez créer une configuration spécifique dans le fichier ~/.ssh/config afin de forcer l’usage de la Yubikey à chaque connexion sur ce host.

1
2
3
4
5
6
Host monserveur
  #ip du serveur distant
  HostName 192.168.1.1
  User jeremie 
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/yubikey_principale

Connexion ssh

Désormais la commande de connexion est la suivante, suivie d’un appui sur la touche tactile de la clef

1
ssh monserveur

C’est presque trop simple ! 🎉

Comment faire sur un nouveau PC ?

Le fichier ~/.ssh/yubikey_principale est généré lors de l’opération ssh-keygen. Dans le cadre d’une clef résidente, ce fichier est seulement descriptif et simplifie l’utilisation (par exemple pour indiquer ce fichier comme étant la clef privée, il servira de pass-through à la Yubikey)

Vous pourriez supprimer ce fichier, et le regénérer exclusivement à partir de la Yubikey. C’est tout l’avantage de cette méthode de clef résidente.
Si vous utilisez un nouveau pc, vous pouvez générer ce fichier descriptif avec la commande suivante :

1
2
cd ~/.ssh
ssh-keygen -K

Cela permet de regénérer dans le répertoire ~/.ssh le fichier descriptif associé à la Yubikey sous le nom : id_ed25519_sk_rk_principale ainsi que la clef publique associée : ~/.ssh/id_ed25519_sk_rk_principale.pub.
Renommer selon l’envie en ~/.ssh/yubikey_principale et ~/.ssh/yubikey_principale.pub par exemple.


Pour aller plus loin

Note
La suite de cet article est optionelle et n’est pas nécessaire à la mise en place de l’accès par clef U2F, mais elle peut vous apporter une aide supplémentaire.

Gestion de l’utilisateur

La première clef que vous générez prend la forme suivante :
ssh:principal 0000000000000000000000000000000000000000000000000000000000000000 openssh

Cette suite de zéro correspond à un encodage du user défini sur cette clef. Cela permet d’identifier vos clefs ssh, malheureusement, l’affichage est encodé en hexadécimal, au lieu de l’unicode.
Si je souhaite ajouter une information sur cette clef, j’ajoute l’option user= comme ci-dessous :

1
ssh-keygen -t ed25519-sk -O "resident" -O "application=ssh:principal" -N "" -f ~/.ssh/yubikey_principale -O user=foo

Le user foo apparaît encodé en hexadécimal :
ssh:principal 666f6f0000000000000000000000000000000000000000000000000000000000 openssh

Supprimer une clef résidente

1
ykman fido credentials delete "ssh:principal"

Si vous possédez plusieurs clefs ssh:principal, il est nécessaire de spécifier l’élément différenciant, comme le user sous sa forme hexadécimale :

1
ykman fido credentials delete "666f6f0000000000000000000000000000000000000000000000000000000000"

Cas particulier de suppression

Si vous avez créé 3 clefs ssh:, ssh:principal et ssh:secondaire, et que vous souhaitez supprimer la clef par défaut ssh: en conservant les deux autres, mais l’utilitaire vous répond alors :

Error: Multiple matches, make the query more specific.

Ajouter les doubles quotes et un espace juste après :

1
ykman fido credentials delete "ssh: "

Désactiver tout autre type d’authentification sur le serveur SSH

Une fois que vous avez réalisé l’authentification par clef FIDO2 avec succès, vous pouvez envisager de supprimer totalement l’accès par mot de passe à votre serveur SSH distant.
Vous garantissez ainsi une protection très forte sur votre machine distante et les attaques par dictionnaire deviendront un mauvais souvenir. Néanmoins, vous devez vous assurer une méthode de connexion de secours en cas de perte de votre clef matérielle.

Attention
Cette procédure peut vous bloquer totalement l’accès SSH si vous réalisez une mauvaise manipulation
Mise en place d'une connexions de secours

Plusieurs possibilités s’offrent à vous :

  • un accès physique à la machine, ou à minimal une connexion “serial” qui simule une connexion avec un clavier physique et un écran. Ce type d’accès permet de vous reconnecter à l’instance distante et avec votre couple (utilisateur / mot de passe) vous pouvez à nouveau vous connecter.
  • en SSH, ajouter une seconde clef FIDO2, ainsi vous conservez une clef en lieu sûr et l’autre sur vous
  • en SSH, ajouter une clef SSH “traditionnelle”, de type ed25519, vous permettant un accès sécurisé de secours. Conservez cette clef offline : sur une clef usb, un keepass, etc…

🌍 Connecté sur votre serveur distant, ouvrez le fichier /etc/ssh/sshd_config et modifiez les lignes suivantes :

  
#désactivation de l'utilisateur root
PermitRootLogin no

#désactivation de l'usage des mots de passe
PasswordAuthentication no
  

🌍 Si votre serveur distant est de type debian/ubuntu, redémarrer le service sshd et vérifier que vous ne pouvez plus vous connecter par mot de passe

1
sudo systemctl restart sshd

Débranchez la Yubikey, et essayez de vous connecter, vous devriez avoir le message suivant : <utilisateur>@<serveur>: Permission denied (publickey).

Seconde clef FIDO2

Si vous choisissez l’option d’avoir une seconde clef FIDO2, un paramètre supplémentaire vous permet d’indiquer au serveur SSH d’autoriser uniquement les connexions du type FIDO2. Ainsi, même les clefs habituelles du type RSA, ed25519, etc.. ne seront pas acceptées !
🌍 Modifier/Ajouter la ligne suivante dans le fichier /etc/ssh/sshd_config et redémarrer le service sshd à nouveau.

  
# restriction des clefs SSH uniquement aux clefs matérielles du type FIDO2 U2F
PubkeyAcceptedKeyTypes sk-ecdsa-sha2-nistp256@openssh.com,sk-ssh-ed25519@openssh.com
  
1
sudo systemctl restart sshd

Désormais seules les clefs FIDO2 U2F seront acceptées comme moyen d’authentification ! 🥳


  1. Documentation OpenSSH de l’ANSSI ↩︎

  2. Controverse ECDSA / ed25519 ↩︎

  3. Release Note OpenSSH 8.2 ↩︎