web-dev-qa-db-fra.com

Comment puis-je exécuter ssh-add automatiquement, sans invite de mot de passe?

Je souhaite communiquer entre plusieurs ordinateurs de mon réseau (Ethernet statique), via SSH. Pour ce faire, je dois exécuter ssh-add chaque fois que je me connecte sur une machine spécifique, comment puis-je le faire pour qu'il soit configuré une fois et qu'il ne me demande pas la phrase secrète chaque fois que je me connecte ou que je redémarre ma machine?

Je sais qu'il existe un moyen d'ajouter des lignes au bash_profile fichier, mais je dois toujours taper le mot de passe chaque fois que je redémarre/me connecte à une machine spécifique.

if [ -z "$SSH_AUTH_SOCK" ] ; then
    eval `ssh-agent -s`
    ssh-add
fi
267
zdun8

Il s'agit d'un exemple typique de compromis entre sécurité et commodité. Heureusement, il existe un certain nombre d'options. La solution la plus appropriée dépend du scénario d'utilisation et du niveau de sécurité souhaité.

clé ssh avec phrase de passe, non ssh-agent

Maintenant, la phrase secrète doit être entrée chaque fois que la clé est utilisée pour l'authentification. Bien que ce soit la meilleure option du point de vue de la sécurité, elle offre la pire convivialité. Cela peut également conduire à choisir une phrase de passe faible afin de réduire le fardeau de la saisie répétée.

clé ssh avec phrase de passe, avec ssh-agent

L'ajout de ce qui suit à ~/.bash_profile Démarrera automatiquement ssh-agent Et chargera la ou les clés ssh lors de la connexion:

if [ -z "$SSH_AUTH_SOCK" ] ; then
  eval `ssh-agent -s`
  ssh-add
fi

Maintenant, la phrase secrète doit être saisie à chaque connexion. Bien que légèrement meilleur du point de vue de l'utilisabilité, cela présente l'inconvénient que ssh-agent Demande la phrase secrète, que la clé soit utilisée ou non pendant la session de connexion. Chaque nouvelle connexion génère également une instance ssh-agent Distincte qui continue de fonctionner avec les clés ajoutées en mémoire même après la déconnexion, sauf si elle est explicitement supprimée.

Pour tuer ssh_agent À la déconnexion, ajoutez ce qui suit à ~/.bash_logout

if [ -n "$SSH_AUTH_SOCK" ] ; then
  eval `/usr/bin/ssh-agent -k`
fi

ou ce qui suit pour ~/.bash_profile

trap 'test -n "$SSH_AUTH_SOCK" && eval `/usr/bin/ssh-agent -k`' 0

La création de plusieurs instances de ssh-agent Peut être évitée en créant une socket de communication persistante pour l'agent à un emplacement fixe dans le système de fichiers, comme dans réponse de Collin Anderson . Il s'agit toutefois d'une amélioration par rapport à la création de plusieurs instances d'agent, sauf si la clé déchiffrée est explicitement supprimée et reste en mémoire après la déconnexion.

Sur les postes de travail, les agents ssh inclus avec l'environnement de bureau, tels que Gnome Keyring SSH Agent , peuvent être une meilleure approche car ils peuvent généralement être effectués pour demander la phrase secrète la première fois que la clé ssh est utilisé pendant une session de connexion et stocke la clé privée déchiffrée en mémoire jusqu'à la fin de la session.

clé ssh avec phrase de passe, avec ssh-ident

ssh-ident est un utilitaire qui peut gérer ssh-agent En votre nom et charger des identités si nécessaire. Il ajoute des clés une seule fois car elles sont nécessaires, quel que soit le nombre de terminaux, ssh ou sessions de connexion qui nécessitent l'accès à un ssh-agent. Il peut également ajouter et utiliser un agent différent et un ensemble de clés différent selon l'hôte auquel se connecter, ou le répertoire ssh est appelé depuis. Cela permet d'isoler les clés lors de l'utilisation du transfert d'agent avec différents hôtes. Il permet également d'utiliser plusieurs comptes sur des sites comme GitHub.

Pour activer ssh-ident, Installez-le et ajoutez l'alias suivant à votre ~/bash_profile:

alias ssh='/path/to/ssh-ident'

clé ssh avec phrase de passe, avec keychain

keychain est un petit utilitaire qui gère ssh-agent en votre nom et permet à ssh-agent de continuer à fonctionner à la fin de la session de connexion. Lors des connexions suivantes, keychain se connectera à l'instance ssh-agent Existante. En pratique, cela signifie que la phrase secrète doit être entrée uniquement lors de la première connexion après un redémarrage. Lors des connexions suivantes, la clé non chiffrée de l'instance ssh-agent Existante est utilisée. Cela peut également être utile pour permettre l'authentification RSA/DSA sans mot de passe dans les travaux cron sans clé ssh sans mot de passe.

Pour activer keychain, installez-le et ajoutez quelque chose comme ceci à ~/.bash_profile:

eval `keychain --agents ssh --eval id_rsa`

Du point de vue de la sécurité, ssh-ident Et keychain sont pires que les instances de ssh-agent Limitées à la durée de vie d'une session particulière, mais elles offrent un haut niveau de commodité. Pour améliorer la sécurité de keychain, certaines personnes ajoutent l'option --clear À leur invocation de trousseau ~/.bash_profile. En faisant cela, les mots de passe doivent être ressaisis lors de la connexion comme ci-dessus, mais les travaux cron auront toujours accès aux clés non chiffrées après la déconnexion de l'utilisateur. keychainpage wiki contient plus d'informations et d'exemples.

clé ssh sans mot de passe

Du point de vue de la sécurité, c'est la pire option car la clé privée est entièrement non protégée au cas où elle serait exposée. C'est cependant le seul moyen de s'assurer que la phrase secrète n'a pas besoin d'être ressaisie après un redémarrage.

clé ssh avec phrase de passe, avec ssh-agent, transmission de la phrase de passe à ssh-add à partir du script

Bien que cela puisse sembler une idée simple de passer la phrase secrète à ssh-add À partir d'un script, par exemple echo "passphrase\n" | ssh-add, Ce n'est pas aussi simple qu'il y paraît que ssh-addne lit pas la phrase secrète de stdin, mais ouvre /dev/tty Directement pour la lecture .

Cela peut être contourné avec expect , un outil pour automatiser les applications interactives. Voici un exemple de script qui ajoute une clé ssh à l'aide d'une phrase secrète stockée dans le script:

#!/usr/bin/expect -f
spawn ssh-add /home/user/.ssh/id_rsa
expect "Enter passphrase for /home/user/.ssh/id_rsa:"
send "passphrase\n";
expect "Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)"
interact

Notez que la phrase secrète étant stockée en texte brut dans le script, du point de vue de la sécurité, ce n'est guère mieux que d'avoir une clé ssh sans mot de passe. Si cette approche doit être utilisée, il est important de s'assurer que le script expect contenant la phrase secrète dispose des autorisations appropriées, le rendant lisible, inscriptible et exécutable uniquement par le propriétaire de la clé.

363
Thomas Nyman

Ajoutez ceci à votre ~/.bashrc, puis vous déconnecter et vous reconnecter 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.

101
Collin Anderson

Pas étroitement lié à la question de l'OP, mais il pourrait être utile à d'autres: puisque 7.2.0 ssh (1) a une option qui permet d'ajouter une clé à ssh-agent lors de la première authentification; l'option est AddKeysToAgent et peut être définie sur yes, no, ask ou confirm, à l'échelle du système ou sur votre _ .ssh/config fichier.

Référence: https://www.openssh.com/txt/release-7.2

16
Guilherme Salazar

ssh-agent met en cache diverses clés ssh déverrouillées, vous pouvez donc avoir des clés ssh protégées par des mots de passe, mais sans avoir à les taper à chaque fois.

Afin de mettre en cache les clés déverrouillées, il doit évidemment déverrouiller ces clés. Pour déverrouiller des clés verrouillées avec une phrase secrète, il doit évidemment connaître ces phrases secrètes.

Toute méthode qui ne nécessite pas l'autorisation d'un être humain (par exemple, "saisir un mot de passe") rendra non seulement votre système non sécurisé; cela rendra également inutile le but de l'agent ssh.

Cela dit, vous pouvez simplement utiliser des clés ssh qui ne sont pas protégées par mot de passe (appuyez sur Enter lorsqu'on lui a demandé un mot de passe lors de la génération des clés). Puisqu'il n'y a pas de mot de passe, ssh-agent n'a pas besoin de vous en demander un pour (pas) le mettre en cache.

7
umläute

Voici une solution de contournement pour automatiser votre phrase secrète SSH.

  1. Créez un script à une ligne qui imprime votre phrase secrète sur la sortie standard, par exemple:

     echo 'echo MY_SSH_PASSWORD' > ~/.print_ssh_password && chmod 700 ~/.print_ssh_password
    

    Important: assurez-vous de copier l'espace de tête dans éviter de stocker votre mot de passe dans votre historique .

Et utilisez l'une des méthodes ci-dessous.

  • en utilisant une approche d'entrée standard:

    cat ~/.ssh/id_rsa | SSH_ASKPASS=~/.print_ssh_password ssh-add -
    
  • ou pipe nommée approche:

    1. Créez un tube nommé (vous pouvez également essayer un substitution de processus ):

      mkfifo --mode 0600 ~/.ssh_fifo
      
    2. Courir ssh-add en spécifiant le programme utilisé pour l'authentification:

      cat ~/.ssh/id_rsa >~/.ssh_fifo | SSH_ASKPASS=~/.print_ssh_password ssh-add ~/.ssh_fifo
      

    Voir: man ssh-add pour en savoir plus sur SSH_ASKPASS.

5
kenorb

Je ne vous recommanderai pas ssh-add (qui doit ouvrir un ssh-agent) lors de la connexion. En effet, vous ne pouvez pas contrôler la fin de la section ssh-agent et vous pouvez créer un risque de sécurité lorsque vous n'avez pas besoin d'utiliser les fichiers de clés dans une section de connexion.

Au lieu de cela, je recommande d'écrire un script qui ouvre le sous-shell de la section d'un agent ssh, avec tous les fichiers clés ajoutés automatiquement, et d'être appelé en cas de besoin pour utiliser ssh. Si vous pouviez l'adopter, lisez la suite.

Vous auriez deux choix:

  1. Supprimez toutes les phrases de passe pour vos clés, qui ont faible sécurité si vos fichiers de clés sont volés. (donc non recommandé )

  2. Utilisez la même phrase secrète pour vos clés. Puis quand vous ssh-add keyfile1 keyfile2 ..., vous n'aurez à taper la phrase secrète qu'une seule fois, par section.

Dans les deux cas, vous pouvez écrire un tel fichier de script "ssh_keys_section.sh" comme ci-dessous:

#!/bin/bash
# This script run a ssh-agent on a sub-Shell and automatically ssh-add all keyfiles at once.
# This agent ends when you type `exit` to close the sub-Shell.
exec ssh-agent bash -c "ssh-add /path/to/keyfile1 /path/to/keyfile2 ...; exec bash"

Remarques:

  • Commande pour modifier ou supprimer la phrase secrète: ssh-keygen -p -f keyfile
  • Dans le sous-shell, vous pouvez même créer plusieurs terminaux partageant les mêmes clés déverrouillées, en utilisant peut-être une commande comme /path/to/yourterminal & (dépend du système d'exploitation)
4
Johnny Wong

J'ai utilisé le script mentionné par steampowered, j'ai fait celui ci-dessous maintenant, car il ne laisse pas de fichiers traîner.

Travailler sur zsh Shell uniquement.

#!/bin/sh

AGENT_BIN=`which ssh-agent`
AGENT_ADD_BIN=`which ssh-add`
AGENT_PID=`ps -fe | grep ${AGENT_BIN} | awk -vuser=$USER -vcmd="$AGENT_BIN" '$1==user && $8==cmd{print $2;exit;}'`
if [ -z "$AGENT_BIN" ]; then
    echo "no ssh agent found!";
    return
fi
if [ "" -eq "$AGENT_PID" ]; then
    if read -sq "YN?Do you want to unlock your ssh keys?"; then
        echo ""
        output=`$AGENT_BIN | sed 's/echo/#echo/g'`
        eval $output
        $AGENT_ADD_BIN
    fi
else
    for f in "/proc/"*
    do
        cmdline=`cat "$f/cmdline"`
        if [ "${AGENT_BIN}" -ef "${cmdline}" ]; then
            export SSH_AUTH_SOCK=`cat $f/net/unix | grep --binary-file=text -oP '((/[^/]*?)+/ssh-[^/]+/agent\.\d+$)'`
            export SSH_AGENT_PID=${f##*/}
            break;
        fi
    done
fi
2
rmc
if [ ! -S ${HOME}/.ssh/ssh_auth_sock ]; then
  eval $(ssh-agent)
  ln -sf "${SSH_AUTH_SOCK}" ${HOME}/.ssh/ssh_auth_sock
fi
export SSH_AUTH_SOCK=${HOME}/.ssh/ssh_auth_sock

ssh_keys=$(find -E ~/.ssh -type f -regex '.*(rsa$|pem)')
ssh_agent_keys=$(ssh-add -l | awk '{key=NF-1; print $key}')

for k in "${ssh_keys}"; do
    for l in "${ssh_agent_keys}"; do
        if [[ ! "${k}" = "${l}" ]]; then
            ssh-add "${k}" > /dev/null 2>&1
        fi
    done
done

Une solution d'authentification unique pour SSH pourrait me conduire à pam_ssh .

Selon cet article , le concept est:

Si vous travaillez avec plusieurs machines basées sur nix via ssh, vous êtes probablement fatigué de devoir constamment saisir votre mot de passe chaque fois que vous souhaitez accéder à une autre boîte. Il existe un moyen sécurisé pour vous permettre d'accéder à toutes les machines auxquelles vous avez accès ssh, sans avoir à entrer un autre mot de passe (autre que celui avec lequel vous vous êtes connecté à l'origine.)


C'est en fait assez simple à faire, vous créez simplement une paire de clés publique/privée pour vous authentifier auprès de vos autres machines, puis demandez à PAM de générer un agent pour charger vos clés après votre connexion, fournissant une solution de connexion unique pour accéder à toutes vos télécommandes Machines. Ce guide vous guidera tout au long de la configuration.

Je n'ai pas vérifié que cela fonctionnerait réellement.

1
Michael
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

Donner du crédit ici: https://www.cygwin.com/ml/cygwin/2001-06/msg00537.html

Cette solution est également approuvée ici: http://mah.everybody.org/docs/ssh

1
steampowered

Ajoutez ceci à votre ~/.bashrc fichier:

ssh-add -L|grep identities > /dev/null && ssh-add /path/to/ssh/private/key
0
Abukamel

Voici le script définitif.

Mettez à jour $ PASSW, puis copiez-collez-le dans votre terminal

# <sshpass> via typinator
# Updated: 2017-01-18_21h36
#
# apt-get update -y; apt-get install expect -qy

# Pass this value to ssh-add
PASSW="myfancypass123"

# Define a name for this script
THIS_SCRIPT="$(date +%Y-%m-%d_%H-%M-%S-%N)".sh

# Create a fresh directory to work from / Clean up
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la


# Output our bash script file - BEGIN
cat <<< '
#!/bin/bash

set -u     # Stop if an unbound variable is referenced
set -e     # Stop on first error
export HISTIGNORE="expect*";

# Normal CMDs
echo && echo "The process should take about 10 seconds:" && echo
eval "$(ssh-agent -s)"; sleep 0.5;

# Define VAR passed when this bash-script was launched
password="$@"

# Launch the expect magic
expect -c "
    spawn ssh-add /root/.ssh/id_rsa
    expect "?assword:"
    send \"$password\r\"
    expect "?password:"
    send \"$password\r\"
    expect eof"

export HISTIGNORE="";
export password="";
' > $THIS_SCRIPT
# Output our bash script file - END


# Ensure we are in the right path
cd ~/temp; ls -la; sleep 1;

# Run the bash script
chmod +x ./$THIS_SCRIPT; ./$THIS_SCRIPT "$PASSW"; unset password;

# Clean up
rm -rf ~/temp; mkdir -p ~/temp; cd ~/temp; ls -la
0
Pascal Andy

Pour ajouter une clé (éventuellement sans mot de passe) et s'assurer que ssh-add ne demandera pas de mot de passe, quoi qu'il arrive, même en cours d'exécution sous X :

DISPLAY= ssh-add -k /path/to/key </dev/null &>/dev/null

L'état de sortie indique la réussite ou l'échec.

0
Keith Cascio

La meilleure façon dont je suis au courant est d'utiliser un script de connexion PAM que j'ai adapté des travaux précédents car je n'ai pas trouvé de réponse satisfaisante dans cette question.

Votre phrase secrète est stockée cryptée avec votre mot de passe système et une fonction de dérivation lourde. Lors de la connexion, votre mot de passe système est utilisé pour déchiffrer votre phrase secrète et l'ajouter à l'agent.

https://github.com/capocasa/systemd-user-pam-ssh

L'avantage par rapport à toutes les autres solutions présentées est qu'il combine une sécurité équivalente à l'exécution manuelle de ssh-add au démarrage sans effort. Il ne nécessite aucun outil supplémentaire et possède une dépendance supplémentaire déjà installée par défaut sur la plupart des systèmes (OpenSSL).

0
cmc

Si vous utilisez Seahorse comme gestionnaire de mots de passe ... ce que vous êtes probablement; D

Une autre solution qui atteint l'objectif que vous recherchez consiste simplement à ajouter les clés ssh à Seahorse pour un déverrouillage automatique lors de la connexion. Le principal avantage est que vous n'avez jamais à entrer de mot de passe pour les clés après vous être connecté via gdm, ou quoi que ce soit avec lequel vous vous connectez, même si les clés ont un mot de passe. Cela nécessite à la fois la clé privée et la clé publique. Ils DOIVENT également suivre une convention de dénomination pour les hippocampes. La valeur par défaut est acceptable (id_rsa pour la clé privée et id_rsa.pub pour la clé publique ... Vraiment tout ce qui est privatekeyname et privatekeyname.pub )

Pour ajouter votre clé SSH à Seahorse pour un déverrouillage automatique lors de la connexion; (sur Fedora25, je ne sais pas où le chemin est sur d'autres distributions bien que son très probablement très similaire)

/lib64/seahorse/seahorse-ssh-askpass /path/to/keys/here

Pour moi, c'était

/lib64/seahorse/seahorse-ssh-askpass ~/.ssh/id_rsa

(Seahorse supposera automatiquement que la clé publique dans mon cas était id_rsa.pub)

Après avoir exécuté la commande, Seahorse ouvrira un joli petit champ de mot de passe gtk pour entrer le mot de passe de la clé privée. ou laissez-le simplement vide si vous avez généré la clé sans mot de passe.

Seahorse ne vous demandera pas si tout s'est bien passé. Vous devrez essayer de ssh dans la machine cible. Ensuite, l'hippocampe vous invitera à déverrouiller graphiquement la clé avec un mot de passe (cela ne se produira qu'une fois), mais cela devrait être un peu différent cette fois; P (c'est également la partie où l'hippocampe fait de l'hippocampe pour ajouter de la magie ssh, je crois, ), et proposez l'option [~ # ~] [~ # ~] pour déverrouiller la clé lors de la connexion, vous devez cochez cette option pour atteindre votre objectif.

Juste parce que je n'ai pas lu toutes les réponses, je recommanderais d'annuler ce que tout le monde vous a dit de faire avec ssh-add avant d'essayer cette réponse. Sinon, cela pourrait entraîner un problème avec vos clés, idk.

0
enconn

Ma configuration sur macOS est la suivante (en .zshrc, ou .bash_profile pour les gens bash):

# Kill then Load the ssh-agent and set the necessary env variables it outputs
sshRestart() {
    # if all else fails
    # pkill -u $(whoami) ssh-agent;

    if [ -n "$SSH_AUTH_SOCK" ] ; then
        eval `/usr/bin/ssh-agent -k`
    fi
    eval `ssh-agent -s`
    ssh-add ~/.ssh/YOUR_KEY_FILE
    echo "Restarted SSH agent"
}

if [ -z "$SSH_AUTH_SOCK" ] || [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]] ; then
    eval `ssh-agent -s` > /dev/null 2>&1
    ssh-add ~/.ssh/YOUR_KEY_FILE > /dev/null 2>&1
fi

Le || [[ $SSH_AUTH_SOCK == *"/private/tmp/"* ]] une partie est nécessaire sur macOS car la valeur par défaut est /private/tmp/com.Apple.launchd.SOMETHINGHERE/Listeners. Sinon, la réponse complète de @Thomas Nyman échoue car $SSH_AUTH_SOCK est toujours défini sur quelque chose.

Puis dans .zlogout (ou .bash_logout pour les gens bash):

if [ -n "$SSH_AUTH_SOCK" ] ; then
    eval `/usr/bin/ssh-agent -k`
fi

Testé sur macOS Mojave 10.14.5

0
Samuel Prevost