A la fin de la présentation, la dernière démonstration consistait à se servir de la Yubikey pour ajouter un verrouillage intelligent d’un poste sous Linux. Dans la théorie, si l’utilisateur ne verrouille pas de lui-même sa session lorsqu’il s’absente, un écran de veille se lance au bout de quelques minutes l’utilisateur est obligé de se ré-authentifier. Dans les faits, il arrive que l’on soit pris d’une urgence; pire encore, certains logiciels peuvent retarder le lancement de l’écran de veille. Un utilisateur malicieux a alors tout le loisir de changer le fond d’écran, ou pire encore…

Nous allons profiter du fait qu’un utilisateur légitime ait en toute vraisemblance attaché sa Yubikey à son porte-clefs pour savoir quand celui-ci s’absente[1]. En pratique, nous allons utiliser udev pour détecter l’insertion ou le retrait d’une clef; Aussi, les Yubikeys peuvent afficher leur numéro de série respectifs sur leurs descripteurs USB[2], ce qui permet en pratique de les identifier.

Dans un premier temps, nous devons créer notre script udev pour gérer la clef. Le script suivant est relativement facile à comprendre sans connaître udev.

/etc/udev/rules.d/85-yubikey.rules

ACTION=="add", ENV{ID_VENDOR}=="Yubico", RUN+="/usr/local/bin/gnome-screensaver-unlock %E{ID_SERIAL_SHORT}"
ACTION=="remove", ENV{ID_VENDOR}=="Yubico", RUN+="/usr/local/bin/gnome-screensaver-lock %E{ID_SERIAL_SHORT}"

La première ligne correspond à l’ajout d’un périphérique pour lequel on va vérifier qu’il s’agit bien d’un Yubikey en regardant la variable d’environnement ID_VENDOR; Si cela correspond, on exécute le script /usr/local/bin/gnome-screensaver-unlock auquel on passe en argument la variable ID_SERIAL_SHORT qui correspond au numéro de série de la clef. La seconde ligne correspond mutatis mutandis au retrait d’une clef.

Ensuite, nous allons créer le script /usr/local/bin/gnome-screensaver-lock qui sera chargé d’effectuer les actions. Il est plus simple dans notre cas de ne pas tout mettre dans le script udev.

/usr/local/bin/gnome-screensaver-lock

#!/bin/sh
 
YUBIKEYS_OWNERSHIP_FILE="/etc/yubikey_ownership"
 
if [ -n "$1" ]; then
        for proc in `pgrep -f gnome-screensaver`; do
                user=`ps -p ${proc} u | sed -e '1d' | awk '{print $1}'`
                for key in `grep -m 1 ${user} ${YUBIKEYS_OWNERSHIP_FILE} | sed -e 's/[^:]*:\([0-9]\{10\}\(:[0-9]\{10\}\)*\).*/\1/' -e 's/:/ /g'`; do
                        if [ $1 = $key ]; then
                                export `grep -z DBUS_SESSION_BUS_ADDRESS /proc/${proc}/environ`
                                if [ `basename $0` = "gnome-screensaver-lock" ]; then
                                        su $user -c "gnome-screensaver-command --lock"
                                elif [ `basename $0` = "gnome-screensaver-unlock" ]; then
                                        su $user -c "gnome-screensaver-command --poke"
                                fi;
                        fi;
                done;
        done;
fi;

Ce script parcours la liste des instances de gnome-screensaver lancées et regarde si l’uid correspond au propriétaire légitime de la clef à l’aide du fichier /etc/yubikey_ownership. Il aurait été possible de faire plus simple, mais ce script fonctionne même dans le cas de configurations multiseat. Par facilité, il s’agit d’un seul et unique script pour les deux actions, l’action étant identifiée à l’aide de basename.

Enfin, il ne reste plus qu’à écrire le fichier de configuration.

/etc/yubikey_ownership

serianox:0000510594:0000505941#1234567890

Bien sûr, il est possible de raffiner, comme par exemple faire le lien entre le numéro de série et l’identité présente sur la clef, ou encore faire cela de façon centralisée. Mais pour le cas concret d’un netbook, c’est amplement suffisant! ;)

nota: Je n’ai pas tout à fait explicité le script. Dans un premier temps, je récupère la variable d’environnement DBUS_SESSION_BUS_ADDRESS pour communiquer avec gnome-screensaver via dbus, et dans un second temps j’envoie soit un lock qui forcera le verrouillage de l’écran, soit un poke qui affichera l’invite. Il est possible de varier le script à loisir.

nota: A venir, soit du déploiement avec pam-auth-config, soit la gestion du fallback quand le serveur d’authentification est indisponible.

nota: Geekfault a réalisé un article introductif aux Yubikeys dont je recommande la lecture pour ceux qui découvrent et veulent exploiter. ;)

nota: Pour finir, dans le cas d’une authentification locale, il est possible de remplacer la Yubikey par une clef USB; Cependant, cela vous expose au risque d’une duplication de celle-ci. :)

Notes

[1] il existe une catégorie d’utilisateur qui laisseraient volontiers leurs clefs de voiture sur une table; on ne peut pas se protéger contre tout non plus

[2] à activer lors de la configuration de la clef