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.

8voto

James Mertz Points 390

Je préfère garder les choses aussi simples que possible : (extrait de ~/.profile )

check-ssh-agent() {
    [ -S "$SSH_AUTH_SOCK" ] && { ssh-add -l >& /dev/null || [ $? -ne 2 ]; }
}

# attempt to connect to a running agent
check-ssh-agent || export SSH_AUTH_SOCK="$(< ~/.tmp/ssh-agent.env)"
# if agent.env data is invalid, start a new one
check-ssh-agent || {
    eval "$(ssh-agent -s)" > /dev/null
    echo "$SSH_AUTH_SOCK" > ~/.tmp/ssh-agent.env
}

Je n'ai pas pensé à utiliser -a avant, mais ça pourrait être plus facile :

check-ssh-agent || export SSH_AUTH_SOCK=~/.tmp/ssh-agent.sock
check-ssh-agent || eval "$(ssh-agent -s -a ~/.tmp/ssh-agent.sock)" > /dev/null

2voto

Encore un exemple à mettre dans votre .bash_profile immédiatement et demandant d'ajouter votre clé par défaut à la connexion. La redirection n'était pas une option dans mon cas.

do-ssh-agent() {
  # function to start the ssh-agent and store the agent details for later logon
  ssh-agent -s > ~/.ssh-agent.conf 2> /dev/null
  . ~/.ssh-agent.conf > /dev/null
}

# set time a key should be kept in seconds
keyage=3600

if [ -f ~/.ssh-agent.conf ] ; then
  . ~/.ssh-agent.conf > /dev/null
  ssh-add -l > /dev/null 2>&1
  # $?=0 means the socket is there and it has a key
  # $?=1 means the socket is there but contains no key
  # $?=2 means the socket is not there or broken
  stat=$?
  if [ $stat -eq 1 ] ; then
    ssh-add -t $keyage > /dev/null 2>&1
  elif [ $stat -eq 2 ] ; then
    rm -f $SSH_AUTH_SOCK
    do-ssh-agent
    ssh-add -t $keyage > /dev/null 2>&1
  fi
else
  do-ssh-agent
  ssh-add -t $keyage > /dev/null 2>&1
fi

2voto

Jasmine Points 2139

Voici ma solution, adaptée de https://superuser.com/a/141233/5255 (dans ce fil) :

# attempt to connect to a running agent - cache SSH_AUTH_SOCK in ~/.ssh/
sagent()
{
    [ -S "$SSH_AUTH_SOCK" ] || export SSH_AUTH_SOCK="$(< ~/.ssh/ssh-agent.env)"

    # if cached agent socket is invalid, start a new one
    [ -S "$SSH_AUTH_SOCK" ] || {
        eval "$(ssh-agent)"
        ssh-add -t 25920000 -K ~/.ssh/id_rsa
        echo "$SSH_AUTH_SOCK" > ~/.ssh/ssh-agent.env
    }
}

2voto

moogs Points 4031

Dans mon cas, j'ai posh-git dans PowerShell et je voulais que cygwin utilise le même agent ssh. J'ai dû faire quelques manipulations de chemin puisqu'ils utilisent des dossiers tmp différents, et le fichier .env créé était UTF16 avec BOM et CR. \LF donc c'était amusant à gérer. Ajouter ce qui suit au .bashrc utilisé par cygwin devrait fonctionner :

# Connect to ssh-agent started by posh-git
SSH_AGENT_ENV=$(cygpath "$LOCALAPPDATA\Temp")
if [ -z $SSH_AUTH_SOCK ] && [ -z $SSH_TTY ]; then  # if no agent & not in ssh
  if [ -f "$SSH_AGENT_ENV/.ssh/SSH_AUTH_SOCK.env" ]; then
    AUTH_SOCK=$(iconv -c -f UTF-16LE -t US-ASCII "$SSH_AGENT_ENV/.ssh/SSH_AUTH_SOCK.env" | tr -d '\r\n')
    export SSH_AUTH_SOCK="${AUTH_SOCK/\/tmp/$SSH_AGENT_ENV}"
    ssh-add -l > /dev/null
    if [ $? = 2 ] ; then
      echo "Failed to setup posh-git ssh-agent using $AUTH_SOCK"
      unset SSH_AUTH_SOCK
    else
      echo "Found posh-git ssh-agent $AUTH_SOCK"
    fi
  else #Start new agent if you want (not shared by posh-git)
    echo "failed to setup posh-git ssh-agent"
    #eval `ssh-agent -s` > /dev/null
  fi
fi

1voto

user193272 Points 524

Créer le fichier ~/ssh-agent.sh

agent_out_file="$HOME/ssh-agent.out"

function initialize {
    pgrep ssh-agent && kill $(pgrep ssh-agent)
    ssh-agent -s > $agent_out_file 
    . $agent_out_file
}

pgrep ssh-agent
if [ $? -eq 0 ]; then # ssh agent running
    ssh-add -l > /dev/null 2>&1
    status=$?
    if [ $status -eq 0 ]; then # can connect to ssh agent and keys available
        echo nothing to do
    elif [ $status -eq 1 ]; then # can connect to ssh agent and no keys available
        echo nothing to do
    elif [ $status -eq 2 ]; then # cannot connect to ssh agent
        . $agent_out_file
    fi
else # ssh agent not running
    initialize   
fi

inclure le fichier dans .bashrc

. ~/ssh-agent.sh

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