PROJET AUTOBLOG


Geekfault

Site original : Geekfault

⇐ retour index

Yubikey : la petite clé qui assure

jeudi 14 avril 2011 à 12:30

Yubikey, c’est une petite clé USB un peu spéciale. Une petite pastille tactile sur le dessus permet de générer un mot de passe à usage unique, qu’un service distant saura utiliser pour vous identifier ou non. C’est pratique, c’est sûr (si c’est bien utilisé), et c’est assez geek pour qu’on en parle.


Le problème

Les mots de passe se multiplient comme des petits pains, surtout chez les geeks. Comme il est impensable de tous les noter dans un petit calepin ou d’utiliser le même partout (on est d’accord ?), il faut sans cesse en inventer de nouveaux et les retenir.

Par ailleurs, si on veut être un peu sérieux, il faut se méfier du terminal que l’on utilise, surtout s’il appartient à un tiers. Qui vous dit que le vilain admin du cyber-café n’a pas un vilain keylogger sur toutes ses machines ? Plus fourbe, qui vous dit qu’il n’y a pas un vilain keylogger malware installé sur le laptop de votre [maman|grand-père|hamster] que vous utilisez en ce moment, “pour dépanner” ? Sans parler d’attaques type MitM et autres joyeusetés …

Arrive la Yubikey. Sans être une solution miracle à tous les problèmes de mot de passe, c’est une façon élégante de se simplifier la vie.

La Yubikey, en bref

Yubikey 2.0, by Yubico

Plutôt que de vous pointer vers le manuel de la Yubikey, je vais en synthétiser quelques passage pour commencer.

La Yubikey fonctionne sur n’importe quel matériel équipé d’un port USB hôte et tournant sous à peu près n’importe quel système d’exploitation supportant un clavier USB (sous Linux, le support HID suffit) : en effet, elle fonctionne en émulant des frappes clavier, sans avoir recours à un driver particulier.

À chaque utilisation, la clé génère une chaîne de caractères unique (appelée OTP pour One Time Password), basée entre autres choses sur une identité propre à la clé, un compteur non-volatile, une horloge et un nombre aléatoire. Cette chaîne est ensuite chiffrée à l’aide d’une clé AES de 128 bits et envoyée à l’hôte. Exemples :

[cc]fifjgjgkhchbirdrfdnlnghhfgrtnnlgedjlftrbdeut
fifjgjgkhchbgefdkbbditfjrlniggevfhenublfnrev
fifjgjgkhchblechfkfhiiuunbtnvgihdfiktncvlhck[/cc]

(on constate que les 12 premiers caractères sont toujours les mêmes : il s’agit là de l’identité de la Yubikey)

De l’autre côté, elle sera déchiffrée à l’aide de la même clé AES. De par l’usage d’un chiffrement symétrique, la sûreté de l’ensemble repose sur une bonne protection de la clé AES. Celle-ci est stockée dans une mémoire non volatile intégrée au microcontrolleur et n’est pas accessible, la configuration de la Yubikey se faisant en écriture seule. Pour récupérer la clé, il faudrait éventuellement sonder physiquement la puce ou analyser son comportement, ce qui implique de casser physiquement la Yubikey et de disposer de matériel de pointe. En d’autres termes, si ce n’est pas complètement adapté aux agents secrets, c’est probablement suffisamment sûr pour le geek moyen que je suis.

Le résultat est enfin vérifié par un serveur de validation : soit celui de Yubico, soit un serveur fait maison. La validation tient compte de plusieurs critères, au-delà de la simple identité. Notamment, la valeur du compteur est examinée : si elle est inférieure ou égale à la dernière valeur reçue, l’OTP est rejeté comme étant un “rejeu” d’un OTP plus ancien.

L’ensemble se résume au schéma suivant (cliquer pour agrandir) :

Fonctionnement de base de la Yubikey

Une application doit donc être configurée (ou modifiée) afin d’accepter un login Yubikey. Comme nous utilisons du logiciel libre, ça se fait en général assez facilement. Nous allons donc voir comment utiliser la Yubikey sous Linux de façon basique, puis nous verrons la configuration dune clé pour une utilisation “indépendante” avec serveur de validation maison.

Utilisation simple

De base, nous utiliserons les services de validation de Yubico. Il s’agit ici de configurer simplement Linux pour identifier un utilisateur en utilisant sa clé.

Application n°1 : login Linux

Tout bon Linux moderne utilise en général Linux-PAM pour tout ce qui touche à l’identification utilisateur. Et comme Yubico a la bonne idée de proposer un module PAM, c’est ce que nous allons utiliser.

Il y a trois dépôts à aller chercher pour construire notre module PAM : celui de la bibliothèque yubico-c-client, celui de l’outil de configurationyubikey-personalization, et enfin yubico-pam lui-même. Pour la suite, je suppose que vous avez déjà git d’installé, en sus des outils habituels (automake, gcc …), et que vous savez aller installer une dépendance manquante (comme curl) au besoin.

Compilations

On commence par compiler la bilbiothèque client.
[cc][smokey@moira yubi]$ git clone https://github.com/Yubico/yubico-c-client
Cloning into yubico-c-client…
remote: Counting objects: 397, done.
remote: Compressing objects: 100% (194/194), done.
remote: Total 397 (delta 233), reused 319 (delta 201)
Receiving objects: 100% (397/397), 94.17 KiB, done.
Resolving deltas: 100% (233/233), done.
[smokey@moira yubi]$ cd yubico-c-client/
[smokey@moira yubico-c-client]$ autoreconf –install
[smokey@moira yubico-c-client]$ ./configure
[smokey@moira yubico-c-client]$ sudo make install
[smokey@moira yubico-c-client]$
[/cc]
Rien que du très classique. La bibliothèque est installée comme il se doit dans /usr/local/lib. Je vous laisse d’ailleurs faire exactement la même chose avec yubikey-personalization dans un répertoire à côté, vous êtes grands après tout.

On peut maintenant répéter l’opération avec yubico-pam, à une astuce près : la dépendance ykpers-1 (yubikey-personalization) a été ajoutée très récemment et se vérifie via pkg-config. Il faut donc indiquer à ce dernier où trouver le fichier .pc qui va bien via la variable d’environnement PKG_CONFIG_PATH. Ce qui donne :
[ccW][smokey@moira yubico-pam]$ cd ..
[smokey@moira yubi]$ git clone https://github.com/Yubico/yubico-pam
[smokey@moira yubi]$ cd yubico-pam/
[smokey@moira yubico-pam]$ autoreconf –install
[smokey@moira yubico-pam]$ PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig ./configure
[smokey@moira yubico-pam]$ sudo make install
[smokey@moira yubico-pam]$[/ccW]

Le module est installé dans /usr/local/lib/security. Pour que PAM puisse l’utiliser, il faut le mettre au bon endroit (et donc être root) :
[cc]# mv /usr/local/lib/security/pam_yubico.so /lib/security/[/cc]

Configuration de PAM

Il faut maintenant indiquer à PAM que l’on veut pouvoir utiliser l’OTP de la Yubikey. Pour ce faire, on modifie /etc/pam.d/login pour y faire ajouter la ligne suivante :
[cc]auth sufficient pam_yubico.so id=16[/cc]
Attention : si vous n’êtes pas très familiers avec PAM, sachez qu’il faut ajouter cette ligne au bon endroit. Je vous recommande de la mettre juste au-dessus de celle du module pam_unix.so. Si vous la placez trop haut, étant donné que le module est ici sufficient (suffisant), il shuntera les modules auth suivants, même s’ils sont required (requis) : pam_securetty ou pam_nologin seraient par exemple rendus inefficaces, ce qui PEUT être grave OU PAS. À vous de voir 🙂

Variantes possibles :

Note : pour observer les messages de debug, il suffit de créer le fichier /var/run/pam-debug.log et de le rendre inscriptible à tous.

Pour finir, il faut renseigner le système sur l’identité des yubikeys des utilisateurs. Il y a deux façons de le faire :

Dans les deux cas, le format du fichier est :
[cc]::…[/cc]
Pour le fichier global, ayez soin d’utiliser une ligne par enregistrement utilisateur. L’ID de chaque Yubikey peut facilement être récupéré en prenant les 12 premiers caractères de n’importe quel OTP généré.

Si tout s’est bien passé, au prochain login, vous devriez voir quelque chose dans ce genre :

yubikey login

Login console avec la Yubikey
On effleure la clé, et c'est gagné 🙂

Application n°2 : authentification à 2 facteurs avec SSH

L’authentification à 2 facteurs est basée, comme son nom l’indique, sur deux moyens d’authentification différents. Ici, nous sommes dans le cas typique de “ce que l’on connaît” (un mot de passe classique) combiné avec “ce que l’on détient” (la Yubikey). Les deux seront combinés pour former un mot de passe hybride, que l’on va charger pam_yupico de valider. En image, ça donne ça :

Yubikey 2 Factor

Fonctionnement de l'authentification à 2 facteurs avec SHS et PAM

La marche à suivre est sensiblement la même que précédemment, sauf bien entendu pour ce qui est de la configuration de PAM. Ici, on va s’intéresser logiquement à /etc/pam.d/sshd. Tout d’abord, on y ajoute la ligne suivante :
[cc]auth required pam_yubico.so id=16[/cc]
Par rapport à tout-à-l’heure, l’utilisation de la Yubikey est ici requise au lieu d’être suffisante. Du coup, on ne risque plus de shunter d’autre modules, mais il faut tout de même placer cette ligne AVANT celle de pam_unix.so.

Ensuite, il faut modifier les paramètres du module pam_unix.so. Celui-ci peut être configuré directement dans /etc/pam.d/sshd (ex. Archlinux), ou être appelé par un @include pointant sur /etc/pam.d/system-auth (ex. Gentoo) ou /etc/pam.d/common-auth (ex. Debian) : à vous d’adapter en fonction de ce que vous avez sous les yeux. L’important est d’ajouter l’option try_first_pass, de façon à ce que la ligne ressemble à ceci :
[cc]auth required pam_unix.so try_first_pass nullok[/cc]

Une fois ces modifications faites, il ne reste plus qu’à vous connecter à la machine distante comme d’habitude ; mais au lieu de taper simplement Entrée pour valider le mot de passe, on va rajouter l’OTP de la Yubikey. En d’autres termes, au lieu de faire mot_de_passe+Entrée, on fait mot_de_passe+toucher_la_yubikey.

Et ça marche ! Sauf si bien sûr vous avez oublié de préciser PasswordAuthentication yes dans votre /etc/ssh/sshd_config … c’était pour voir si vous suiviez 😉

yubikey en ssh

Login SSH. Par défaut, SSH propose d'utiliser la clé publique s'il en trouve une : taper entrée pour passer à l'étape suivante.

Utilisation avancée

Dans cette partie, un peu plus technique, nous allons aborder la configuration d’une Yubikey et le montage d’un serveur de validation. Mais avant tout …

ATTENTION

La Yubikey est “write-only”. Ceci signifie que lors d’une opération de configuration, les réglages précédents sont irrémédiablement perdus. Notamment, si vous écrasez la configuration par défaut, votre clé ne pourra plus vous identifier auprès de Yubico.
Par ailleurs, si vous décidez de protéger la clé par un code d’accès, et que vous oubliez ce code, vous aurez gagné un joli bout de plastique très décoratif …

Ceci dit, passons aux choses sérieuses.

Configuration de la clé

Sous Linux, le seul outil disponible pour l’instant est en ligne de commande. Si ça vous fait peur, il y a des équivalent pour clicodrome Windows ou Mac OS. Choisissez ici celui qui vous convient le mieux 😉

Le dépôt de l’outil de configuration (ou personalization en anglais) est ici : https://github.com/Yubico/yubikey-personalization.git. Je ne reviens pas sur la procédure d’installation, elle est identique aux précédentes et détaillée sur le wiki du projet. D’ailleurs, si vous avez suivi la partie sur la configuration de PAM, vous l’avez déjà installé 😉

Une fois compilé, je vous engage vivement à jeter un oeil à l’aide en ligne : [cci]ykpersonalize -h [/cci]

L’option la plus importante à mes yeux est -1 ou -2 : c’est ainsi que l’on choisit la configuration que l’on souhaite modifier. En effet, les Yubikeys version 2.0 et plus possèdent deux “emplacements” différents, contre un seul dans la première version. Par défaut sur une clé 2.0 par exemple, l’emplacement 1 est paramétré pour une identification OTP auprès des serveurs de Yubico, et l’emplacement 2 est vide.

Le paramétrage le plus fréquemment rencontré est d’assigner un mot de passe statique à la configuraion 2, mot de passe qui sera accessible par un contact long (≃ 2s). La manipulation est ici très simple :
[cc lines=”16″]smokey@moira:~$ sudo ykpersonalize -2
Password:
Firmware version 2.0.2 Touch level 1792 Program sequence 6

Passphrase to create AES key: crévindiou
Configuration data to be written to key configuration 2:

fixed: m:
uid: h:000000000000
key: h:459b2b6c6f4c511d543919efbad3051a
acc_code: h:000000000000
ticket_flags: APPEND_CR
config_flags: STATIC_TICKET|STRONG_PW1|STRONG_PW2|MAN_UPDATE
extended_flags:

Commit? (y/n) [n]:[/cc]
Il ne reste plus qu’à valider par un “y” pour sauvegarder la configuration.
Notez que vous n’êtes pas obligés de taper des bêtises (comme mon “crévindiou”) pour créer la clé AES. Le résultat sera ici un mot de passe statique du style :
[cci]è(IFejhdkkjnvrtbdeggeffvbknvbulg[/cci].

Note : Pourquoi sudo ? tout simplement parce que les permissions de /dev/bus/usb/xxx/yyy n’autorisent en général pas l’utilisateur lambda à écrire sur un port USB.

Il est également possible de créer une configuration “OTP Yubikey” similaire à la configuration par défaut. Je fais ici le choix d’utiliser l’emplacement 2, afin de conserver la configuration d’origine dans l’emplacement 1. Or, l’outil ykpersonalize considère par défaut que l’option -2 va de pair avec une configuration statique ; il faut donc désactiver les options liées au mot de passe statique pour écrire une configuration OTP dans l’emplacement 2 (d’où les 4 options -o-xxx). Si ce n’est pas clair, faites tourner “à vide” (sans écrire) ykpersonalize avec -1 et -2, et observez les différents config_flags. Ici, ça nous donne :
[ccW lines=”16″]smokey@moira:~/tmp/yubiserve$ sudo ykpersonalize -2 -o-static-ticket -o-strong-pw1 -o-strong-pw2 -o-man-update -ofixed=cccccccccccc
Firmware version 2.0.2 Touch level 1792 Program sequence 6

Passphrase to create AES key:
Configuration data to be written to key configuration 2:

fixed: m:cccccccccccc
uid: h:000000000000
key: h:8ebfe5cd3dad48f2c5008d686ea5b384
acc_code: h:000000000000
ticket_flags: APPEND_CR
config_flags:
extended_flags:

Commit? (y/n) [n]: y
smokey@moira:~/tmp/yubiserve$
[/ccW]

La configuration 2 de la clé est donc faite pour l’identité cccccccccccc et avec la clé AES 8ebfe5cd3dad48f2c5008d686ea5b384. Nous allons voir maintenant comment utiliser cette configuration avec un serveur de validation maison.

Serveur de validation “maison”

Comme me le faisait remarquer un certain Spyou, confier à un tiers la vérification du droit d’accès à son infrastructure n’est probablement pas l’idée du siècle. Mon infrastructure se limite à peu de choses, mais tant qu’à faire, autant garder la vérification en interne. Il s’agit donc maintenant de monter son propre serveur de vérification. Yubico en référence quelques-uns, je vais ici détailler l’installation et la configuration du plus simple, YubiServe. Et quand je dis simple, je pèse mes mots : le tout tient en 2 scripts Python 🙂

Avant tout, je vous recommande d’éviter la version 3.1, qui (chez moi en tout cas) contient des “?” partout là où on attend des tabulations. Je vais donc partir du trunk svn :
[cc]svn checkout http://yubico-yubiserve.googlecode.com/svn/trunk/ yubiserve[/cc]

Ceci fait, suivons les instructions du README.
Tout d’abord, on crée un certificat SSL :
[ccW]openssl req -new -x509 -keyout yubiserve.pem -out yubiserve.pem -days 365 -nodes[/ccW]

Ensuite, si vous avez installé Python 2 et 3 sur votre système, il vous faudra peut-être modifier un peu les scripts dbconf.py et yubiserve.py : soit pour faire pointer l’interpréteur vers python2, soit pour modifier l’appel au module sqlite en sqlite3. Par défaut, YubiServe utilisera une base sqlite (déjà présente d’origine), mais il suffit de modifier le fichier de configuration (yubiserve.cfg) pour utiliser une base MySQL à la place.

Il est temps maintenant d’ajouter une clé au serveur. Utilisons donc dbconf.py, qui prend en arguments un “nickname” permettant d’identifier facilement la clé, ainsi que l’uid et la clé AES utilisés lors du paramétrage (cf. plus haut).
[ccW]smokey@moira:~/tmp/yubiserve$ ./dbconf.py -ya smokey cccccccccccc 000000000000 8ebfe5cd3dad48f2c5008d686ea5b384
Key ‘smokey’ added to database.
smokey@moira:~/tmp/yubiserve$[/ccW]
On en profite pour ajouter aussi l’identité cccccccccccc dans le /home/utilisateur/.yubico/authorized_yubikeys qui va bien.

Lançons le serveur :
[cc]smokey@moira:~/tmp/yubiserve$ ./yubiserve.py
HTTP Server is running.
[/cc]

Il ne reste plus qu’à essayer le tout, en faisant pointer un navigateur sur http://127.0.0.1:8000/, ce qui donne normalement ceci :
YubiServe

Il suffit alors d’envoyer l’OTP dans le champ prévu à cet effet pour obtenir le résultat :

Ça fonctionne ! Mais comment faire en sorte d’interroger ce serveur ? Nous allons voir le cas du module PAM, configuré dans la partie précédente.

PAM + Serveur de validation maison

Rappelez-vous, la configuration ressemblait à ça :
[cc]auth required pam_yubico.so id=16[/cc]
Nous allons la transformer en ça :
[ccW]auth required pam_yubico.so id=1 debug url=http://127.0.0.1:8000/wsapi/2.0/verify?id=%d&otp=%s[/ccW]

Par ailleurs, vous aurez remarqué que l’on a précisé un id en argument à pam_yubico. Cet id numérique sera passé via l’URL au serveur de validation : il faut donc qu’il soit défini côté serveur. Nous allons donc ajouter une clé d’API :
[cc]smokey@moira:~/tmp/yubiserve$ ./dbconf.py -aa test-ssh
New API Key for ‘test2’: ‘WGZydWozbHQyVW9BM092cy9nMTk=’
Your API Key ID is: 1[/cc]
Bien entendu, notre “API Key ID” est 1 seulement si c’est le premier à être créé ; l’important est qu’il existe.

C’est fini ! On peut maintenant s’identifier auprès de PAM avec la clé re-configurée par nos soins.

N’oublions pas …

Il serait imprudent de penser que la Yubikey est la réponse à tout. Elle n’est qu’un élément de plus dans une stratégie de sûreté qui se doit d’être solide par ailleurs (c’est toujours le maillon le plus faible qui compte). Si votre login est connu et que vous n’utilisez *que* la Yubikey pour vous connecter, c’est déjà beaucoup moins sûr qu’un schéma à 2 facteurs.

Par ailleurs, comme la Yubikey fonctionne en émulant une saisie clavier, son comportement dépendra du type de clavier utilisé sur le terminal ; si la plupart des dispositions classiques (azerty/qwerty) ne devraient pas poser problème, il en est tout autrement pour les dispositions plus “exotiques” (comme bepo) ou utilisant des caractères non-latins (cyrilliques par exemple). Ce n’est pas un point bloquant en soi, vu qu’il suffit de changer temporairement la configuration du clavier, mais je me devais de le souligner, vu qu’on m’avait posé la question.

Conclusion et informations additionnelles

Tout comme une clé SSH avec un user-agent, une Yubikey permet d’éviter de taper des mots de passe à chaque login. C’est un gain de temps et de tranquillité d’esprit. C’est aussi une sécurité supplémentaire car les mots de passe générés ne sont pas réutilisables, ce qui invalide toute forme d’attaque par rejeu. Cerise sur le gâteau, on trouve déjà pas mal de solutions logicielles libres, venant de Yubico ou d’ailleurs, permettant de tirer le maximum de sa clé. Que demander de plus ? 🙂

Liens