Thực thi lệnh rsync trên ssh với một tác nhân ssh thông qua crontab


18

tôi có một cronjob:

0 9 * * * rsync -a mydir remote_machine:

tôi đã cài đặt cái này với 'crontab -e'. Tôi có một ssh-agent đang chạy và khi tôi thực thi lệnh rsync, nó hoạt động với bất kỳ mục nhập tương tác hoặc mật khẩu nào của người dùng, nhưng cronjob không thành công với thông báo sau:

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]

Tại sao điều này không làm việc? tôi biết các cronjobs chạy w / me với tư cách là người dùng (nếu tôi chạy '* * * * * touch / tmp / a' tôi sở hữu tệp) vì vậy tôi giả sử rsync đang đăng nhập khi tôi sử dụng khóa riêng của mình ...

Câu trả lời:


10

Shell phiên cron của bạn không có kiến ​​thức về tác nhân ssh, vì vậy không thể nói chuyện với nó.

Khi tác nhân được bắt đầu, bạn có thể đặt thông tin cần thiết cho đại lý ở một nơi nào đó để phiên cron nhận.

Thí dụ:

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

Sau đó thêm chìa khóa của bạn cho các đại lý.

ssh-add $HOME/.ssh/id_dsa

Bây giờ công việc định kỳ của bạn nên làm điều này trước khi thử sử dụng ssh:

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

... sau đó, phiên ssh sẽ diễn ra bình thường.


vì vậy tôi có đặt tất cả các tác nhân tác nhân vào một tập lệnh theo lệnh rsync không, hoặc tôi có thể đặt nó trong một số tệp .profile hoặc .bashrc mà cron tải tự động khi nó khởi động trình bao cho cronjob không?
aaron

Tôi sẽ đặt các tác nhân tác nhân trong tập lệnh chạy lệnh rsync.
David Mackffy

3
tất cả những gì tôi cần là cung cấp các biến env SSH_AUTH_SOCK và SSH_AGENT_PID (tôi đặt chúng vào .ssh-agent thay vì .ssh / agent /) vì vậy đây là những gì tôi đã kết thúc với: "0 9 * * *. $ HOME / .ssh -agent && rsync -av $ HOME / mydir remote_machine: "
aaron

1
Tất cả những thứ không cần thiết này, hãy sử dụng móc khóa
cmcginty

@cmcginty ai nói móc khóa là có sẵn, hoặc có thể được cài đặt?
zb226

19

móc khóa là thứ bạn cần! Chỉ cần cài đặt nó và thêm mã theo dõi trong .bash_profile(hoặc tương đương) của bạn:

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

Đối với config.fish ( 2 ):

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

Sau đó sử dụng mã dưới đây trong tập lệnh của bạn để tải các biến môi trường ssh-agent:

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

Đối với cá:

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

Nếu khóa của bạn có cụm mật khẩu, móc khóa sẽ hỏi bạn một lần (hợp lệ cho đến khi bạn khởi động lại máy hoặc giết ssh-agent).

Lưu ý: móc khóa cũng tạo mã cshfishvỏ, vì vậy chỉ cần thay thế hậu tố "-sh" thành "-csh" hoặc "-fish".


1
$ HOSTNAME không được xác định trong môi trường cron, nhưng ngoài ra đây là giải pháp tốt nhất
cmcginty

nếu tôi sử dụng khóa rsa, tôi có thay đổi móc khóa ~ / .ssh / id_dsa thành móc khóa ~ / .ssh / id_rsa không?
Katafalkas

@Katafalkas chính xác!
semente

@Casey Tôi đã cập nhật câu trả lời của tôi. Bây giờ là tương thích với cron.
semente

Tôi đã thêm hướng dẫn tốt hơn cho cá.
Elijah Lynn

2

Tôi không có đủ đại diện để bỏ phiếu cho câu trả lời đầu tiên, nhưng nó đã giải quyết được vấn đề mà tôi đang gặp phải. Về mặt ssh-agent, bạn có thể đã có một cái đang chạy. Đây là tập lệnh để trích xuất SSH_AGENT_PID & SSH_AUTH_SOCK từ môi trường mà không có bất kỳ nội dung bổ sung nào để lưu khi khởi động ssh-agent. (Giả sử rằng bạn có perl)

Đặt sau đây trong một kịch bản. (ví dụ findagent.pl)

và bên trong tập lệnh cron của bạn thêm dòng:

eval `{đường dẫn đến tập lệnh} / 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

Tôi cho rằng bạn đang sử dụng khóa dựa trên xác thực để xác thực chính mình với máy từ xa. Hãy thử dòng dưới đây:

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

Trong đó .ssh / id_rsa là đường dẫn đến khóa riêng của bạn. Đây là dòng chính xác tôi đang sử dụng để thực hiện sao lưu và nó luôn hoạt động tốt với tôi.

Lời chúc tốt đẹp nhất,
Fabian


0

Thay vào đó, thay vì sử dụng tác nhân ssh, tôi đã tạo tập lệnh của mình để xuất RSYNC_RSH = "ssh -i /home/user/.ssh/id_rsa" bỏ đặt SSH_AGENT_PID hủy đặt SSH_AUTH_SOCK trước khi gọi rsync. Bằng cách đặt nó vào RSYNC_RSH thay vì sử dụng '-e ...', điều đó giúp dễ dàng điều chỉnh tệp id đang được sử dụng dựa trên máy chủ.

Hy vọng điều này sẽ giúp, B


Tôi không nghĩ rằng nó hoạt động nếu bạn có cụm mật khẩu trên khóa của mình
cmcginty
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.