Eseguire il comando rsync su ssh con un agente ssh tramite crontab


18

ho un cronjob:

0 9 * * * rsync -a mydir remote_machine:

ho installato questo con 'crontab -e'. ho un agente ssh in esecuzione e quando eseguo il comando rsync stesso funziona senza alcuna interazione dell'utente o immissione della password, ma il cronjob fallisce con il seguente messaggio:

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]

perché non funziona? so che i cronjobs eseguono w / me come utente (se eseguo '* * * * * touch / tmp / a' possiedo il file) quindi presumo che rsync stia effettuando il login come me usando la mia chiave privata ...

Risposte:


10

La tua shell di sessione cron non ha conoscenza dell'agente ssh, quindi non posso parlarci.

Quando viene avviato l'agente, è possibile inserire le informazioni necessarie per l'agente in un punto in cui raccogliere la sessione cron.

Esempio:

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

Quindi aggiungere la chiave all'agente.

ssh-add $HOME/.ssh/id_dsa

Ora il tuo cron job dovrebbe farlo prima di provare a usare ssh:

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

... dopo di che, la sessione ssh dovrebbe procedere normalmente.


quindi inserisco tutte le cose dell'agente in uno script seguito dal comando rsync, oppure posso metterlo in un file .profile o .bashrc che cron carica automaticamente quando avvia una shell per un cronjob?
Aaron,

Vorrei mettere le cose dell'agente nello script che esegue il comando rsync.
David Mackintosh,

3
tutto ciò di cui avevo bisogno era di generare le variabili env SSH_AUTH_SOCK e SSH_AGENT_PID (le ho messe in .ssh-agent invece di .ssh / agent /) quindi questo è quello che ho finito con: "0 9 * * *. $ HOME / .ssh -agent && rsync -av $ HOME / mydir remote_machine: "
aaron

1
Tutto ciò non è necessario, usa il portachiavi
cmcginty del

@cmcginty chi dice che il portachiavi è disponibile o può essere installato?
zb226,

19

portachiavi è quello che ti serve! Basta installarlo e aggiungere il seguente codice nel tuo .bash_profile(o equivalente):

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

Per config.fish ( 2 ):

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

Quindi utilizzare il codice seguente nello script per caricare le variabili di ambiente ssh-agent:

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

Per i pesci:

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

Se la tua chiave ha una passphphase, il portachiavi ti chiederà una volta (valido fino a quando non riavvii la macchina o uccidi l'agente ssh).

Nota: il portachiavi genera anche codice cshe fishshell, quindi sostituisci il suffisso "-sh" in "-csh" o "-fish".


1
$ HOSTNAME non è definito in ambiente cron, ma a parte questo è la soluzione migliore
cmcginty

se uso chiavi rsa, cambio portachiavi ~ / .ssh / id_dsa in portachiavi ~ / .ssh / id_rsa?
Katafalkas,

@Katafalkas esattamente!
semente,

@ Casey ho aggiornato la mia risposta. Ora è compatibile con cron.
semente,

Ho aggiunto istruzioni migliori per Fish.
Elijah Lynn,

2

Non ho abbastanza rappresentante per votare la prima risposta, ma ha risolto il problema che stavo avendo. In termini di ssh-agent, potresti già averne uno in esecuzione. Ecco uno script per estrarre SSH_AGENT_PID e SSH_AUTH_SOCK dall'ambiente senza ulteriori elementi da salvare all'avvio di ssh-agent. (Suppone di avere perl)

Inserisci quanto segue in uno script. (ad esempio findagent.pl)

e all'interno del tuo cron script aggiungi la riga:

eval `{percorso dello 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

Suppongo che tu stia utilizzando l'autenticazione basata su chiave per autenticarti con la macchina remota. Prova la riga qui sotto:

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

Dove .ssh / id_rsa è il percorso della tua chiave privata. Questa è la linea esatta che sto usando per fare i miei backup e funziona sempre bene per me.

I migliori auguri,
Fabian


0

In alternativa, invece di utilizzare l'agente ssh, ho creato il mio script per esportare RSYNC_RSH = "ssh -i /home/user/.ssh/id_rsa" unset SSH_AGENT_PID unset SSH_AUTH_SOCK prima di invocare rsync. Inserendolo in RSYNC_RSH invece di usare '-e ...' ha reso semplice la regolazione del file id utilizzato in base all'host.

Spero che questo aiuti, B


Non credo che
funzioni
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.