web-dev-qa-db-fra.com

Démarrer ssh-agent à la connexion

J'ai un site en tant que dépôt Git distant extrait de Bitbucket.com en utilisant un alias SSH. Je peux démarrer manuellement ssh-agent sur mon serveur mais je dois le faire chaque fois que je me connecte via SSH.

Je lance manuellement ssh-agent:

eval ssh-agent $Shell

Puis j'ajoute l'agent:

ssh-add ~/.ssh/bitbucket_id

Ensuite, il apparaît lorsque je fais:

ssh-add -l

Et je suis prêt à partir. Y a-t-il un moyen d'automatiser ce processus afin que je ne l'aie pas à chaque fois que je me connecte? Le serveur exécute RedHat 6.2 (Santiago).

216
Pathsofdesign

Veuillez parcourir cet article. Vous pouvez trouver cela très utile:

http://mah.everybody.org/docs/ssh

Juste au cas où le lien ci-dessus disparaîtrait un jour, je capture l'essentiel de la solution ci-dessous:

Cette solution de Joseph M. Reagle par Daniel Starin:

Ajoutez ceci à votre .bash_profile

_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 -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
else
    start_agent;
fi
_

Cette version est particulièrement agréable dans la mesure où elle verra si vous avez déjà démarré ssh-agent et, si elle ne le trouve pas, le lancera et enregistrera les paramètres pour qu'ils soient utilisables la prochaine fois que vous lancerez une application. Coquille.

316
Litmus

Sur Arch Linux, ce qui suit fonctionne vraiment bien (devrait fonctionner sur toutes les distributions basées sur systemd):

Créez un service utilisateur systemd en mettant ce qui suit à ~/.config/systemd/user/ssh-agent.service:

[Unit]
Description=SSH key agent

[Service]
Type=forking
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK

[Install]
WantedBy=default.target

Le shell d'installation doit avoir une variable d'environnement pour le socket (.bash_profile, .zshrc, ...):

export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"

Activez le service pour qu'il soit automatiquement lancé à la connexion et démarrez-le:

systemctl --user enable ssh-agent
systemctl --user start ssh-agent

Ajoutez le paramètre de configuration suivant à votre fichier de configuration ssh ~/.ssh/config (cela fonctionne depuis SSH 7.2):

AddKeysToAgent  yes

Ceci demandera au client ssh de toujours ajouter la clé à un agent en cours d'exécution, il n'est donc pas nécessaire de le faire au préalable par ssh.

80
spheenik

Vieille question, mais je suis tombé sur une situation similaire. Ne pensez pas que la réponse ci-dessus réalise pleinement ce qui est nécessaire. La pièce manquante est keychain; installez-le s'il ne l'est pas déjà.

Sudo apt-get install keychain

Ajoutez ensuite la ligne suivante à votre ~/.bashrc

eval $(keychain --eval id_rsa)

Ceci démarrera le ssh-agent s'il n'est pas en cours d'exécution, vous y connectera le cas échéant, chargera les variables d'environnement ssh-agent dans votre shell et chargera votre clé ssh.

Remplacez id_rsa par la clé privée que vous souhaitez charger dans ~/.ssh.

Référence

https://unix.stackexchange.com/questions/90853/how-can-i-run-ssh-add-automatically-without-password-Prompt

47
xelber

La solution acceptée présente les inconvénients suivants:

  • c'est compliqué à entretenir;
  • il évalue le fichier de stockage qui peut entraîner des erreurs ou une faille de sécurité;
  • il démarre l'agent mais ne l'arrête pas, ce qui revient à laisser la clé dans le contact.

Si vos clés ne nécessitent pas de mot de passe, je suggère la solution suivante. Ajoutez les éléments suivants à votre .bash_profiletoute fin (modifiez la liste des clés selon vos besoins):

exec ssh-agent $BASH -s 10<&0 << EOF
    ssh-add ~/.ssh/your_key1.rsa \
            ~/.ssh/your_key2.rsa &> /dev/null
    exec $BASH <&10-
EOF

Il présente les avantages suivants:

  • solution beaucoup plus simple;
  • la session de l'agent se termine à la fin de la session bash.

Il y a des inconvénients possibles:

  • la commande interactive ssh-add n'influencera qu'une session, ce qui n'est en fait un problème que dans des circonstances très inhabituelles;
  • inutilisable si la saisie du mot de passe est requise;
  • shell démarré devient non-login (ce qui n'influence rien autant que je sache).

Notez que plusieurs processus ssh-agent ne sont pas un inconvénient, car ils ne nécessitent pas plus de mémoire ou de temps processeur.

37
midenok

Ajoutez ceci à votre ~/.bashrc, puis déconnectez-vous et reconnectez-vous pour prendre effet.

if [ ! -S ~/.ssh/ssh_auth_sock ]; then
  eval `ssh-agent`
  ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock
ssh-add -l > /dev/null || ssh-add

Cela ne devrait demander un mot de passe que la première fois que vous vous connectez après chaque redémarrage. Il continuera à réutiliser le même ssh-agent tant qu'il reste en cours d'exécution.

21
Collin Anderson

J'avais donc l'habitude d'utiliser les approches décrites ci-dessus, mais je préfère en quelque sorte que l'agent meure à la fin de ma dernière session bash. C'est un peu plus long que les autres solutions, mais c'est mon approche préférée. L'idée de base est que la première session bash démarre ssh-agent. Ensuite, chaque session bash supplémentaire recherche le fichier de configuration (~/.ssh/.agent_env). Si tel est le cas et qu'une session est en cours d'exécution, indiquez l'environnement et créez un lien physique vers le fichier de socket dans /tmp (il doit figurer sur le même système de fichiers que le fichier de socket d'origine). Lorsque les sessions bash sont arrêtées, chacune supprime son propre lien physique. La dernière session à fermer constatera que les liens physiques ont 2 liens (le lien dur et l’original), la suppression de la socket du processus et la suppression du processus aboutiront à 0, laissant un environnement propre après la fermeture de la dernière session bash.

# Start ssh-agent to keep you logged in with keys, use `ssh-add` to log in
agent=`pgrep ssh-agent -u $USER` # get only your agents           
if [[ "$agent" == "" || ! -e ~/.ssh/.agent_env ]]; then
    # if no agents or environment file is missing create a new one
    # remove old agents / environment variable files
    kill $agent running
    rm ~/.ssh/.agent_env 

    # restart
    eval `ssh-agent` 
    echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ~/.ssh/.agent_env             
    echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ~/.ssh/.agent_env             
fi

# create our own hardlink to the socket (with random name)           
source ~/.ssh/.agent_env                                                    
MYSOCK=/tmp/ssh_agent.${RANDOM}.sock                                        
ln -T $SSH_AUTH_SOCK $MYSOCK                                                
export SSH_AUTH_SOCK=$MYSOCK                                                

end_agent()                                                                     
{
    # if we are the last holder of a hardlink, then kill the agent
    nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`                             
    if [[ "$nhard" -eq 2 ]]; then                                               
        rm ~/.ssh/.agent_env                                                    
        ssh-agent -k                                                            
    fi                                                                          
    rm $SSH_AUTH_SOCK                                                           
}                                                                               
trap end_agent EXIT                                                             
set +x              
7
Micah

Juste pour ajouter une autre solution: P, j’ai opté pour une combinaison des solutions de @spheenik et de @ collin-anderson.

 # Ensure that we have an ssh config with AddKeysToAgent set to true
 if [ ! -f ~/.ssh/config ] || ! cat ~/.ssh/config | grep AddKeysToAgent | grep yes > /dev/null; then
     echo "AddKeysToAgent  yes" >> ~/.ssh/config
 fi
 # Ensure a ssh-agent is running so you only have to enter keys once
 if [ ! -S ~/.ssh/ssh_auth_sock ]; then
   eval `ssh-agent`
   ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock
 fi
 export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock

Pourrait être un peu plus élégant mais c'est simple et lisible. Cette solution:

  • s'assure que AddKeysToAgent yes est dans votre configuration ssh afin que les clés soient automatiquement ajoutées lors de l'utilisation
  • ne vous invite pas à entrer des mots de passe lors de la connexion (là encore, un mot de passe à usage unique apparaît lors de la première utilisation)
  • démarre silencieusement un agent ssh s'il n'en a pas déjà démarré

Commentaires bienvenus :)

5
Keego

Je l'ai résolu en l'ajoutant à/etc/profile - à l'échelle du système (ou à l'utilisateur .profile local ou .bash_profile).

# SSH-AGENT 
#!/usr/bin/env bash
SERVICE='ssh-agent'
WHOAMI=`who am i |awk '{print $1}'`

if pgrep -u $WHOAMI $SERVICE >/dev/null
then
echo $SERVICE running.
else
echo $SERVICE not running.
echo starting
ssh-agent > ~/.ssh/agent_env
fi
. ~/.ssh/agent_env

Cela démarre un nouvel agent ssh s'il n'est pas en cours d'exécution pour l'utilisateur ou redéfinit le paramètre env si ssh-agent est en cours d'exécution.

2
TheFrog

Désolé d'être si tard:

Les utilisateurs du poisson peuvent utiliser ce script pour faire la même chose.

# content has to be in .config/fish/config.fish
# if it does not exist, create the file
setenv SSH_ENV $HOME/.ssh/environment

function start_agent                                                                                                                                                                    
    echo "Initializing new SSH agent ..."
    ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV
    echo "succeeded"
    chmod 600 $SSH_ENV 
    . $SSH_ENV > /dev/null
    ssh-add
end

function test_identities                                                                                                                                                                
    ssh-add -l | grep "The agent has no identities" > /dev/null
    if [ $status -eq 0 ]
        ssh-add
        if [ $status -eq 2 ]
            start_agent
        end
    end
end

if [ -n "$SSH_AGENT_PID" ] 
    ps -ef | grep $SSH_AGENT_PID | grep ssh-agent > /dev/null
    if [ $status -eq 0 ]
        test_identities
    end  
else
    if [ -f $SSH_ENV ]
        . $SSH_ENV > /dev/null
    end  
    ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep ssh-agent > /dev/null
    if [ $status -eq 0 ]
        test_identities
    else 
        start_agent
    end  
end
2
Daniel Gerber

Aimez beaucoup vos réponses. Cela facilitait beaucoup le travail à partir de cygwin / linux. J'ai combiné les fonctions de début et de fin pour le sécuriser.

SSH_ENV="$HOME/.ssh/.agent_env"

function start_agent {
    echo "Initialising new SSH agent..."

    eval `/usr/bin/ssh-agent`
    echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ${SSH_ENV}
    echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ${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 -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
        start_agent;
    }
else
    start_agent;
fi

# create our own hardlink to the socket (with random name)
MYSOCK=/tmp/ssh_agent.${RANDOM}.sock
ln -T $SSH_AUTH_SOCK $MYSOCK
export SSH_AUTH_SOCK=$MYSOCK

end_agent()
{
    # if we are the last holder of a hardlink, then kill the agent
    nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'`
    if [[ "$nhard" -eq 2 ]]; then
        rm ${SSH_ENV}
        /usr/bin/ssh-agent -k
    fi
    rm $SSH_AUTH_SOCK
}
trap end_agent EXIT
set +x

merci encore

1
Knelis