Le mpg-blog

LaTeX et autres geekeries

Petit hack de ssh-agent

with 2 comments

Si vous êtes un utilisateur régulier de ssh et que vous ne connaissez pas encore ssh-agent, ruez-vous sur sa documentation. En deux mots, ses principales fonctionnalités sont :

  1. Garder en cache une copie déchiffrée de votre clé privée ssh, pour vous éviter d’avoir à saisir constamment la passphrase.
  2. Permettre de voyager facilement entre différentes machines : les demandes d’authentification sont retransmises à la machine initiale.

Mon propos ici n’est pas de faire un guide de l’usage normal de ssh-agent mais plutôt de montrer comment le détourner légèrement. L’usage prévu est que les processus fils de ssh-agent ou du shell où il a été lancé aient dans leur environnement une variable SSH_AUTH_SOCK pointant vers un socket Unix permettant de communiquer avec l’agent.

Il n’y a pas longtemps, j’ai voulu utiliser une connexion ssh dans le contexte d’un hook post-commit de Subversion. Il s’agit par exemple de pages web que je tiens sous contrôle de version, et dont je souhaite qu’à chaque commit elles soient mises à jour sur le serveur web (auquel j’ai accès par ssh). Ça tombe bien, je me connecte à mon serveur SVN par la méthode ssh+svn://, et en principe j’ai toujours un ssh-agent qui tourne sur la machine de départ. Problème, les hooks SVN démarrent avec un environnement essentiellement vide.

Il faut donc essayer de retrouver soi-même les informations de ssh-agent. Ce n’est pas très difficile, en fait l’accès au socket n’est protégé que par les permissions au niveau du système de fichiers. Les quelques lignes de Perl suivantes trouvent un socket ssh-agent actif s’il y en a un et positionnent la variable SSH_AUTH_SOCK pour permettre son utilisation facile par les fils du processus courant.

sub hack_ssh_agent {
    return if $ENV{'SSH_AUTH_SOCK'};
    $success = 0;
    opendir TMP, "/tmp";
    for my $dir (grep (/ssh-/, readdir TMP)) {
        opendir TEST, "/tmp/$dir";
        ($agent) = grep (/^agent/, readdir (TEST));
        closedir (TEST);
        $ENV{'SSH_AUTH_SOCK'} = "/tmp/$dir/$agent";
        print "Trying /tmp/$dir/$agent\n";
        $success = (system("ssh localhost true") == 0);
        last if $success;
    }
    closedir TMP;
    die "Pas moyen de trouver un ssh-agent.\n" unless $success;
}

Outre l’utilisation présentée, à savoir récupérer les informations permettant de se connecter à un ssh-agent depuis un processus qui n’en est pas un descendant, je pense que ces quelques lignes de code ont un intérêt pédagogique. Elles montrent qu’il est très facile pour root de récupérer les ssh-agent de tous les utilisateurs s’il le désire. (Notons quand même que ça ne lui donne pas accès à la clé déchiffrée de façon permanente, non plus : c’est déjà ça.)

En soi, ce n’est pas un grand problème de sécurité : si on a pas confiance en root, on est de toutes façons déjà dans… les problèmes jusqu’au cou. Par contre, j’ai un compte sur la machine d’un ami en qui j’ai en général toute confiance mais qui est souvent très blagueur en matière informatique. J’ai donc pris soin d’insérer ForwardAgent no dans mon ~/.ssh/config concernant sa machine.

Written by mpg

janvier 14th, 2009 at 12:23

Posted in Geekeries diverses

Tagged with ,

2 Responses to 'Petit hack de ssh-agent'

  1. Je m’insurge !!!! Je ne me reconnais absolument pas dans l’ »ami très blagueur en matière informatique », et ne poursuivrait cette conversation qu’en présence de mon avocat !

    Julien

    30 jan 09 at 17:24

  2. Tu as bien raison de ne pas te reconnaître ! En fait je pensais surtout à la personne à cause de qui j’ai déjà dû changer un mot de passe root à la hâte… Ah, c’est toi aussi ? Bah zut alors. :-)

    mpg

    30 jan 09 at 17:35