ssh-agent et crontab – existe-t-il un bon moyen de les satisfaire?

J’ai écrit un script simple qui envoie les journaux d’activité de svn tous les soirs à nos développeurs. Jusqu’à présent, je l’ai exécuté sur la même machine que le repository svn, donc je n’avais pas à m’inquiéter de l’authentification, je pouvais simplement utiliser le style de fichier svn ‘: ///.

Maintenant, j’exécute le script sur un ordinateur personnel, accédant à un référentiel distant, j’ai donc dû passer à svn + ssh: // chemins. Avec ssh-key bien configuré, je n’ai jamais à entrer de mots de passe pour accéder au repository svn dans des circonstances normales.

Cependant, crontab n’a pas eu access à ssh-keys / ssh-agent. J’ai lu à propos de ce problème quelques endroits sur le Web, et on y fait également allusion, sans résolution:

Pourquoi ssh échoue-t-il à partir de crontab mais succède à une exécution depuis une ligne de commande?

Ma solution a été d’append ceci au début du script:

### TOTAL HACK TO MAKE SSH-KEYS WORK ### eval `ssh-agent -s` 

Cela semble fonctionner sous MacOSX 10.6.

Ma question est la suivante: à quel point est-ce terrible et existe-t-il une meilleure solution?

Lorsque vous exécutez ssh-agent -s, il lance un processus en arrière-plan que vous devrez tuer plus tard. Donc, le minimum est de changer votre hack en quelque chose comme:

 eval `ssh-agent -s` svn stuff kill $SSH_AGENT_PID 

Cependant, je ne comprends pas comment ce hack fonctionne. L’exécution d’un agent sans exécuter ssh-add ne chargera aucune clé. Peut-être que ssh-agent de MacOS se comporte différemment de sa page de manuel .

En outre…

Si votre clé a une phrase secrète, le trousseau vous le demandera une fois (valide jusqu’à ce que vous redémarriez la machine ou que vous tuiez le ssh-agent).

trousseau est ce dont vous avez besoin! Installez-le simplement et ajoutez le code suivant dans votre fichier .bash_profile:

 keychain ~/.ssh/id_dsa 

Utilisez donc le code ci-dessous dans votre script pour charger les variables d’environnement ssh-agent:

 . ~/.keychain/$HOSTNAME-sh 

Remarque: le trousseau génère également du code pour csh et fish shells.

Copié la réponse de https://serverfault.com/questions/92683/execute-rsync-command-over-ssh-with-an-ssh-agent-via-crontab

J’avais un problème similaire. Mon script (qui reposait sur des clés ssh) fonctionnait lorsque je l’exécutais manuellement, mais échouait lors de l’exécution avec crontab.

Définition manuelle de la clé appropriée avec

 ssh -i /path/to/key 

n’a pas fonctionné

Mais finalement, j’ai découvert que SSH_AUTH_SOCK était vide lorsque la crontab exécutait SSH. Je ne savais pas exactement pourquoi, mais je viens

 env | grep SSH 

copié la valeur renvoyée et ajouté cette définition à la tête de ma crontab.

 SSH_AUTH_SOCK="/tmp/value-you-get-from-above-command" 

Je ne suis pas très au courant de ce qui se passe ici, mais cela a résolu mon problème. La crontab fonctionne bien maintenant.

Une façon de récupérer le pid et le socket de l’exécution de ssh-agent serait.

 SSH_AGENT_PID=`pgrep -U $USER ssh-agent` for PID in $SSH_AGENT_PID; do let "FPID = $PID - 1" FILE=`find /tmp -path "*ssh*" -type s -iname "agent.$FPID"` export SSH_AGENT_PID="$PID" export SSH_AUTH_SOCK="$FILE" done 

Cela suppose bien sûr que pgrep soit installé sur le système et qu’il n’existe qu’un seul agent ssh-agent ou, dans le cas de plusieurs, il remplacera celui que pgrep trouvera en dernier.

Ma solution – basée sur les pra ‘- a été légèrement améliorée pour tuer le processus même en cas d’échec du script:

 eval `ssh-agent` function cleanup { /bin/kill $SSH_AGENT_PID } trap cleanup EXIT ssh-add svn-stuff 

Notez que je dois appeler ssh-add sur ma machine (scientifique Linux 6).

Pour configurer des processus automatisés sans hacks automatisés de mot de passe / phrase secrète, j’utilise un fichier IdentityFile distinct qui ne comporte pas de phrase secrète et limite les entrées authorized_keys des machines cibles avec from = “automated.machine.com” … etc.

J’ai configuré un hôte remoteAuto dans .ssh / config:

 Host remoteAuto HostName remote.machine.edu IdentityFile ~/.ssh/id_localAuto 

et les remote.machine.edu:.ssh/authorized_keys avec:

 ... from="192.168.1.777" ssh-rsa ABCDEFGabcdefg.... ... 

Ensuite, ssh n’a pas besoin de l’autorisation authentifiée en externe fournie par ssh-agent ou keychain.

Inspiré par certaines des autres réponses ici (en particulier celles de vpk), je suis arrivé avec l’entrée crontab suivante, qui ne nécessite pas de script externe:

 PATH=/usr/bin:/bin:/usr/sbin:/sbin * * * * * SSH_AUTH_SOCK=$(lsof -a -p $(pgrep ssh-agent) -U -F n | sed -n 's/^n//p') ssh hostname remote-command-here 

Voici une solution qui fonctionnera si vous ne pouvez pas utiliser le trousseau et si vous ne pouvez pas démarrer un agent ssh à partir de votre script (par exemple, parce que votre clé est protégée par une phrase secrète).

Exécutez ceci une fois:

 nohup ssh-agent > .ssh-agent-file & . ssh-agent-file ssh-add # you'd enter your passphrase here 

Dans le script que vous exécutez depuis cron:

 # start of script . ${HOME}/.ssh-agent-file # now your key is available 

Bien sûr, cela permet à quiconque peut lire «~ / .ssh-agent-file» et le socket correspondant d’utiliser vos identifiants ssh, donc soyez prudent avec n’importe quel environnement multi-utilisateur.

En supposant que vous ayez déjà configuré les parameters SSH et que ce script fonctionne correctement à partir du terminal, l’utilisation du trousseau est certainement le moyen le plus simple de vous assurer que le script fonctionne correctement dans crontab.

Le trousseau n’étant pas inclus dans la plupart des dérivations Unix / Linux, voici la procédure pas à pas.

1. Téléchargez le package RPM approprié en fonction de la version de votre système d’exploitation à l’ adresse http://pkgs.repoforge.org/keychain/ . Exemple pour CentOS 6:

 wget http://pkgs.repoforge.org/keychain/keychain-2.7.0-1.el6.rf.noarch.rpm 

2. Installez le paquet:

 sudo rpm -Uvh keychain-2.7.0-1.el6.rf.noarch.rpm 

3. Générez des fichiers de trousseau pour votre clé SSH, ils seront situés dans le répertoire ~ / .keychain. Exemple pour id_rsa:

 keychain ~/.ssh/id_rsa 

4. Ajoutez la ligne suivante à votre script n’importe où avant la première commande utilisant l’authentification SSH:

 source ~/.keychain/$HOSTNAME-sh 

J’ai personnellement essayé d’éviter d’utiliser des programmes supplémentaires pour cela, mais tout ce que j’ai essayé ne fonctionnait pas. Et cela a bien fonctionné.

Votre solution fonctionne mais elle engendrera un nouveau processus d’agent à chaque fois, comme indiqué par une autre réponse.

J’ai fait face à des problèmes similaires et j’ai trouvé cet article de blog utile, ainsi que le script shell de Wayne Walker mentionné dans le blog sur github .

Bonne chance!