Exécutez la commande rsync sur ssh avec un agent ssh via crontab


18

j'ai un cronjob:

0 9 * * * rsync -a mydir remote_machine:

j'ai installé cela avec 'crontab -e'. j'ai un ssh-agent en cours d'exécution, et lorsque j'exécute la commande rsync elle-même, elle fonctionne sans aucune interaction utilisateur ou entrée de mot de passe, mais le cronjob échoue avec le message suivant:

Date: Wed,  9 Dec 2009 11:11:00 -0600 (CST)
From: Cron Daemon <me@my_machine.my_domain>
To: me@my_machine.my_domain
Subject: Cron <me@my_machine> rsync -a /home/me/mydir remote_machine:

Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,gssapi-with-mic,password).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at /SourceCache/rsync/rsync-35.2/rsync/io.c(452)
[sender=2.6.9]

pourquoi ça ne marche pas? je sais que les cronjobs fonctionnent avec moi en tant qu'utilisateur (si je lance '* * * * * touch / tmp / a' je suis propriétaire du fichier), je suppose donc que rsync se connecte en tant que moi en utilisant ma clé privée ...

Réponses:


10

Votre shell de session cron n'a aucune connaissance de l'agent ssh, donc vous ne pouvez pas lui parler.

Lorsque l'agent est démarré, vous pouvez placer les informations nécessaires à l'agent quelque part pour la session cron à récupérer.

Exemple:

AGENT="ssh-agent -s"
if [ ! -d $HOME/.ssh/agent ]; then
        mkdir -p $HOME/.ssh/agent
fi
#
# Start an agent if there isn't one running already.
#
pid=`ps -u$LOGNAME | grep ssh-age | awk '{print $1}'`
if [ -z "$pid" ]; then
        $AGENT | grep -v echo > $HOME/.ssh/agent/$HOST & pid=$!
        sleep 1 # Let it fork and stuff
fi

Ajoutez ensuite votre clé à l'agent.

ssh-add $HOME/.ssh/id_dsa

Votre tâche cron devrait maintenant faire cela avant d'essayer d'utiliser ssh:

#
# Get our parent to pick up the required SSH env vars.
#
. $HOME/.ssh/agent/$HOST

... après quoi, la session ssh devrait se dérouler normalement.


alors dois-je mettre tous les trucs d'agent dans un script suivi de la commande rsync, ou puis-je le mettre dans un fichier .profile ou .bashrc que cron charge automatiquement lorsqu'il démarre un shell pour un cronjob?
aaron

Je mettrais les trucs d'agent dans le script qui exécute la commande rsync.
David Mackintosh

3
tout ce dont j'avais besoin était de trouver les variables env SSH_AUTH_SOCK et SSH_AGENT_PID (je les ai mises dans .ssh-agent au lieu de .ssh / agent /) donc c'est ce que j'ai fini avec: "0 9 * * *. $ HOME / .ssh -agent && rsync -av $ HOME / mydir remote_machine: "
aaron

1
Tout cela n'est pas nécessaire, utilisez le trousseau
cmcginty

@cmcginty qui dit que le trousseau est disponible ou peut être installé?
zb226

19

porte - clés est ce dont vous avez besoin! Installez-le simplement et ajoutez le code suivant dans votre .bash_profile(ou équivalent):

if [ -x /usr/bin/keychain ]; then
  /usr/bin/keychain --quiet --clear $HOME/.ssh/id_rsa
fi

Pour config.fish ( 2 ):

if not status --is-interactive
   keychain --eval --quiet --quick $HOME/.ssh/id_rsa
end

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

. ~/.keychain/`/bin/hostname`-sh

Pour le poisson:

source $HOME/.keychain/(hostname)-fish

Si votre clé a un mot de passe, le trousseau vous demandera une fois (valable jusqu'à ce que vous redémarriez la machine ou tuiez l'agent ssh).

Remarque: le trousseau génère également du code vers cshet des fishshells, il suffit donc de remplacer le suffixe "-sh" par "-csh" ou "-fish".


1
$ HOSTNAME n'est pas défini dans l'environnement cron, mais à part cela, c'est la meilleure solution
cmcginty

si j'utilise des clés rsa, dois-je changer le trousseau ~ / .ssh / id_dsa en trousseau ~ / .ssh / id_rsa?
Katafalkas

@Katafalkas exactement!
semente

@Casey J'ai mis à jour ma réponse. Est maintenant compatible avec cron.
semente

J'ai ajouté de meilleures instructions pour Fish.
Elijah Lynn

2

Je n'ai pas assez de représentants pour voter la première réponse, mais cela a résolu le problème que j'avais. En termes de ssh-agent, vous en avez peut-être déjà un en cours d'exécution. Voici un script pour extraire le SSH_AGENT_PID & SSH_AUTH_SOCK de l'environnement sans aucun truc supplémentaire à enregistrer au démarrage de ssh-agent. (Suppose que vous avez perl)

Mettez ce qui suit dans un script. (par exemple findagent.pl)

et à l'intérieur de votre script cron ajoutez la ligne:

eval `{chemin du script} / findagent.pl`


\#!/usr/bin/perl -w
use strict;
my $agents = `ls -tr /tmp/ssh-*/*`;
my @agents;
(@agents) = split/\n/,$agents;

my $sshpid = `ps aux|grep ssh-agent|grep -v grep|awk '{print \$2}'|head -1`;
chomp($sshpid);
my @parts;
for (@agents) {
  chomp($_);
  if (!$_) { next; }
  my $agentfile = $_;
  (@parts) = split/\./,$agentfile;
  my $masterpid = `ps aux|grep $parts[1]|grep enlightenment`;
  if ($agentfile =~ m/$parts[1]/) {
    my $line1 = "SSH_AUTH_SOCK=" . $agentfile . '; export SSH_AUTH_SOCK';
    my $line2 = 'SSH_AGENT_PID=' . $sshpid . '; export SSH_AGENT_PID;';
    my $line3 = 'echo Agent pid ' . $sshpid . ';';
    print("$line1\n$line2\n$line3\n");
    last;
  } else {
    next;
  }
}

1

Je suppose que vous utilisez l'authentification par clé pour vous authentifier avec la machine distante. Essayez la ligne ci-dessous:

rsync -av --delete -e "ssh -i .ssh/id_rsa" mydir user@host.tld:~/backupDir

Où .ssh / id_rsa est le chemin d'accès à votre clé privée. C'est la ligne exacte que j'utilise pour faire mes sauvegardes et cela fonctionne toujours bien pour moi.

Meilleurs voeux,
Fabian


0

Comme alternative, au lieu d'utiliser l'agent ssh, j'ai fait exporter mon script RSYNC_RSH = "ssh -i /home/user/.ssh/id_rsa" unset SSH_AGENT_PID unset SSH_AUTH_SOCK avant d'appeler rsync. En le plaçant dans RSYNC_RSH au lieu d'utiliser '-e ...', il a été facile d'ajuster le fichier id utilisé en fonction de l'hôte.

J'espère que cela vous aide, B


Je ne pense pas que cela fonctionne si vous avez une phrase secrète sur votre clé
cmcginty
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.