81 votes

Partager le même `ssh-agent` entre plusieurs sessions de connexion

Existe-t-il un moyen pratique de s'assurer que toutes les connexions d'un utilisateur donné (c'est-à-dire moi) utilisent le même agent ssh ? J'ai bricolé un script pour que cela fonctionne la plupart du temps, mais je soupçonnais depuis le début qu'il y avait un moyen de le faire que j'avais juste manqué. De plus, depuis cette époque, il y a eu des avancées étonnantes dans la technologie informatique, comme par exemple ce site web.

Donc le but ici est que

  • à chaque fois que je me connecte à la boîte, que ce soit via SSH, ou dans une session graphique lancée depuis gdm/kdm/etc, ou sur une console :
    • si mon nom d'utilisateur n'a pas actuellement un ssh-agent en cours d'exécution, l'un d'entre eux est démarré, les variables d'environnement sont exportées, et ssh-add appelé.
    • sinon, les coordonnées de l'agent existant sont exportées dans les variables d'environnement de la session de connexion.

Cette facilité est particulièrement précieuse lorsque la boîte en question est utilisée comme point de relais lorsque ssh dans une troisième boîte. Dans ce cas, cela évite d'avoir à taper la phrase de passe de la clé privée à chaque fois que vous vous connectez par ssh et que vous voulez, par exemple, faire git push ou quelque chose comme ça.

Le script donné ci-dessous fait cela de manière plutôt fiable, bien qu'il ait récemment bâclé lorsque X a planté et que j'ai ensuite lancé une autre session graphique. Il se peut qu'il y ait eu d'autres problèmes dans ce cas.

Voici mon script mauvais est bon. Je le tire de mon .bashrc .

# ssh-agent-procure.bash
# v0.6.4
# ensures that all shells sourcing this file in profile/rc scripts use the same ssh-agent.
# copyright me, now; licensed under the DWTFYWT license.

mkdir -p "$HOME/etc/ssh";

function ssh-procure-launch-agent {
    eval `ssh-agent -s -a ~/etc/ssh/ssh-agent-socket`;
    ssh-add;
}

if [ ! $SSH_AGENT_PID ]; then
  if [ -e ~/etc/ssh/ssh-agent-socket ] ; then
    SSH_AGENT_PID=`ps -fC ssh-agent |grep 'etc/ssh/ssh-agent-socket' |sed -r 's/^\S+\s+(\S+).*$/\1/'`; 
    if [[ $SSH_AGENT_PID =~ [0-9]+ ]]; then
      # in this case the agent has already been launched and we are just attaching to it. 
      ##++  It should check that this pid is actually active & belongs to an ssh instance
      export SSH_AGENT_PID;
      SSH_AUTH_SOCK=~/etc/ssh/ssh-agent-socket; export SSH_AUTH_SOCK;
    else
      # in this case there is no agent running, so the socket file is left over from a graceless agent termination.
      rm ~/etc/ssh/ssh-agent-socket;
      ssh-procure-launch-agent;
    fi;
  else
    ssh-procure-launch-agent;
  fi;
fi;

S'il vous plaît, dites-moi qu'il y a un meilleur moyen de faire ça. Aussi, s'il vous plaît, ne pinailler pas sur les incohérences/manques (par exemple, mettre le nom de l'auteur dans le texte). var des choses dans etc ) ; j'ai écrit ceci il y a un certain temps et j'ai depuis appris beaucoup de choses.

53voto

h355ian Points 471

ssh -A [user@]remotehost

Je pense que ça pourrait être ce que vous cherchez. Utilisez le commutateur -A lorsque vous exécutez ssh forward votre ssh-agent. Voici un cas d'utilisation :

J'ai un serveur distant sur lequel se trouvent des dépôts git avec un remote pointant vers github. Sans un agent ssh lancé dans une session écran, je dois entrer la phrase de passe pour ma clé afin de faire un "git pull origin master". Oups ! De plus, je dois avoir mon privé installée sur le serveur distant - plus de Boooo !

Au lieu de cela, il suffit d'utiliser ssh -A [user@]remotehost transmet mon agent ssh local. Maintenant, je n'ai même plus besoin que ma clé privée existe sur l'hôte distant. Je ne pense pas qu'il soit nécessaire d'utiliser des scripts avec ssh-agent.

35voto

Zed Points 519

Je pourrais aussi bien ajouter ma propre variation dans le mélange :

function sshagent_findsockets {
    find /tmp -uid $(id -u) -type s -name agent.\* 2>/dev/null
}

function sshagent_testsocket {
    if [ ! -x "$(which ssh-add)" ] ; then
        echo "ssh-add is not available; agent testing aborted"
        return 1
    fi

    if [ X"$1" != X ] ; then
        export SSH_AUTH_SOCK=$1
    fi

    if [ X"$SSH_AUTH_SOCK" = X ] ; then
        return 2
    fi

    if [ -S $SSH_AUTH_SOCK ] ; then
        ssh-add -l > /dev/null
        if [ $? = 2 ] ; then
            echo "Socket $SSH_AUTH_SOCK is dead!  Deleting!"
            rm -f $SSH_AUTH_SOCK
            return 4
        else
            echo "Found ssh-agent $SSH_AUTH_SOCK"
            return 0
        fi
    else
        echo "$SSH_AUTH_SOCK is not a socket!"
        return 3
    fi
}

function sshagent_init {
    # ssh agent sockets can be attached to a ssh daemon process or an
    # ssh-agent process.

    AGENTFOUND=0

    # Attempt to find and use the ssh-agent in the current environment
    if sshagent_testsocket ; then AGENTFOUND=1 ; fi

    # If there is no agent in the environment, search /tmp for
    # possible agents to reuse before starting a fresh ssh-agent
    # process.
    if [ $AGENTFOUND = 0 ] ; then
        for agentsocket in $(sshagent_findsockets) ; do
            if [ $AGENTFOUND != 0 ] ; then break ; fi
            if sshagent_testsocket $agentsocket ; then AGENTFOUND=1 ; fi
        done
    fi

    # If at this point we still haven't located an agent, it's time to
    # start a new one
    if [ $AGENTFOUND = 0 ] ; then
        eval `ssh-agent`
    fi

    # Clean up
    unset AGENTFOUND
    unset agentsocket

    # Finally, show what keys are currently in the agent
    ssh-add -l
}

alias sagent="sshagent_init"

Et ensuite, à chaque fois que je me connecte, si je quiere un agent attaché (ce qui n'est pas toujours le cas), je tape simplement sagent .

25voto

En voici un joli qui fonctionne aussi avec Cygwin :

SSH_ENV=$HOME/.ssh/environment

function start_agent {
     echo "Initialising new SSH agent..."
     /usr/bin/ssh-agent | sed 's/^echo/#echo/' > ${SSH_ENV}
     echo succeeded
     chmod 600 ${SSH_ENV}
     . ${SSH_ENV} > /dev/null
     /usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
     . ${SSH_ENV} > /dev/null
     #ps ${SSH_AGENT_PID} doesn't work under cywgin
     ps -efp ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
         start_agent;
     }
else
     start_agent;
fi

Ajoutez-le à votre fichier .bash_profile ou .bashrc.

Source : http://www.cygwin.com/ml/cygwin/2001-06/msg00537.html

12voto

morynicz Points 141

Essayez d'utiliser le porte-clés, il est fait pour ça. http://www.gentoo.org/doc/en/keychain-guide.xml

9voto

MarkMo Points 125

J'ai récemment commencé à l'utiliser :

https://github.com/ccontavalli/ssh-ident

Tout ce que j'ai à faire est d'ajouter :

  alias ssh=/path/to/ssh-ident

Dans mon fichier .bashrc. Le script s'occupe de :

  • créer un agent au moment où il est le plus nécessaire
  • charger les clés nécessaires sur demande
  • partager des agents sur plusieurs sessions de connexion
  • gérer plusieurs agents, un pour chaque "identité" que j'utilise en ligne, et utiliser le bon agent en fonction de l'hôte auquel je me connecte ou du répertoire de travail actuel.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X