Pour un travailler sur un projet hébergé sur codeberg j’ai créé un compte et j’ai voulu ajouter ma clef SSH dérivée de ma Yubikey. Mais celle-ci n’est que de 2048 bits et n’est pas acceptée :-(

Ma clef SSH habituelle est gérée par ma Yubikey. La Yubikey contient ma clef OpenPGP de laquelle est dérivée ma clef SSH. Et cela fonctionne très bien. Le seul point négatif est que la Yubikey étant ancienne la taille de la clef SSH ne peut pas dépasser 2048 bits.

Jusqu’à présent cela ne m’avait pas posé de problème. Mais chez codeberg la taille minimale est de 3072. Cette taille est héritée de gitea pour répondre à une exigence du German Federal Office for Information Security.

Je n’ai pas très envide de créer une nouvelle clef et j’apprécie le fonctionnement avec Yubikey. Heureusement en cherchant un peu je suis tombé sur une solution : utiliser le support FIDO2. Et c’est plus simple que PKCS#11 et même OpenPGP.

ℹ️ Note : J’ai trouvé cette page qui décrit très bien le fonctionnement et les différents cas d’usages.

FIDO2

Rapidement, FIDO2 est un protocole ouvert d’authentification conçu pour le web (on parle aussi de U2F, WebAuthn). Il utilise un mécanisme de clef publique/clef privée. La Yubikey contient la clef privée et on touche la clef pour vérifier la présence de l’utilisateur et valider l’utilisation.

On peut utiliser ce protocole pour générer des clefs SSH. On parle parfois de clef SK, pour Security Key.

Il y a deux variantes, une clef résidente ou non résidente. La clef résidente est enregistrée sur la clef Yubikey (ou autre tant que c’est du fido2) alors que pour la clef non résidente rien n’est sur la Yubikey (ni sur la machine). On va préférer pour notre cas l’utilisation d’une clef non résidente même si l’autre type peut avoir d’autres usages.

Clef SSH non résidente

Quand on génère une clef SSH “sk” on obtient :

  • une clef publique,
  • et une clef privée qui contient un “key handle”.

Le “key handle” est une clef privée mais qui ne peut pas être utilisée directement. Elle nécessite un secret pour être déchiffrée et utilisée. Et ce secret c’est notre Yubikey qui va le fournir. Alors pas vraiment, comme souvent la Yubikey va effectuer une opération de déchiffrement et fournir le résultat pour valider qu’elle connaît le secret. De plus la Yubikey va attendre qu’on touche le bouton de la clef pour autoriser l’opération.

Seule, la clef privée SSH ne peut pas être utilisée. Et si un tiers veut utiliser la clef depuis notre machine il faut encore qu’on valide l’opération en touchant le bouton.

Création de la clef

Ma clef Yubikey étant ancienne elle ne supporte pas ed25519 et je dois utiliser ecdsa. La procédure de création est la même dans les deux cas.

> ssh-keygen -t ecdsa-sk
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter file in which to save the key (/home/montfort/.ssh/id_ecdsa_sk):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/montfort/.ssh/id_ecdsa_sk
Your public key has been saved in /home/montfort/.ssh/id_ecdsa_sk.pub
The key fingerprint is: SHA256:... montfort@superpc
The key's randomart image is:
+-[ECDSA-SK 256]--+

Il faut toucher la Yubikey puis saisir une passphrase. Et on obtient nos deux clefs. On peut les utiliser comme habituellement, la seule différence étant qu’il faudra toucher la Yubikey lorque cela sera demandé.

❯ ssh git@codeberg.org
Enter passphrase for key '/home/montfort/.ssh/id_ecdsa_sk':
Confirm user presence for key ECDSA-SK SHA256:...
User presence confirmed
PTY allocation request failed on channel 0
Hi there, montfort! You've successfully authenticated with the key named montfort@superpc, but Forgejo does not provide shell access.

Utilisation

A l’utilisation je n’ai pas de problème particulier. Tout fonctionne bien pour faire du git, on peut préciser dans ~/.ssh/config quelle clef utiliser pour quelle machine.

Par contre je n’ai pas réussi à l’ajouter dans le ssh-agent. Je n’ai pas cherché la raison. Une solution est de lancer eval $(ssh-agent) et après on peut ajouter la clef. Une autre est d’ajouter IdentityAgent none sous Host * ou une machine précise. Pour l’instant cela ne gêne pas (trop) mon utilisation. Je pense qu’on n’ajoute que le “key handle” et qu’ensuite il faut quand même toucher la clef.

On peut faire du ssh forwarding sans problème car la clef n’est jamais transmise complète.

Je trouve l’utilisation plus simple qu’avec OpenPGP et on n’est pas obligé d’avoir une Yubikey, une clef qui fait simplement FIDO2 suffit.

Je suis bien content d’avoir trouvé cette solution pour pouvoir utiliser codeberg.