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.