使用SSH密钥与cron

4

我正在使用一个通过ssh与服务器同步的cron脚本。

当我直接运行这些命令时,它们可以很好地运行,但是当我将它们作为cron任务运行时,cron会记录错误的权限问题。我认为这是因为cron用户没有访问ssh密钥的权限。

这是我需要cron运行的代码:

rsync --progress -rvze ssh my_user@myserver/root_folder folder/

我能把ssh密钥传递到cron文件或脚本本身吗?如果可以,你能提供一个像上面那样的示例吗?

你是否在crontab中指定以root身份运行脚本? - hek2mgl
它适用于哪个用户?你是以哪个用户的身份运行cron的?这个密钥有密码吗? - that other guy
密钥确实有密码。在crontab中,脚本不会以root身份运行。我将crontab设置为我的常用用户,并且ssh密钥也是为了同一用户。我不想以root身份运行是因为我不希望它期望输入任何密码,我只希望它能正确地在后台运行。 - johncorser
1
在后台没有人输入密码短语,这就是为什么它失败的原因。创建一个没有密码短语的新密钥。如果需要,你可以在服务器端限制只允许使用rsync。 - that other guy
4个回答

17

我知道这个帖子已经很旧了,但是为了那些像我一样遇到这个问题的人,请看以下两个选项:

  • 按照lihao建议的方式传递密钥。
  • 添加正确的SSH环境变量,以便它选择正确的密钥,就像在您的正常环境中运行一样。

对于第二个选项,并假设您的cron作业以正确的用户身份运行(否则还有更多要在环境中正确设置的东西),只需运行:

env|grep -i ssh

会有一行内容:

SSH_AUTH_SOCK=/run/user/1000/keyring/ssh

对于您来说,用户ID可能不同。从那里开始,您只需要将以下行添加到您的脚本中:

if [ -z "$SSH_AUTH_SOCK" ]
then
    export SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
fi
希望这有所帮助!

1
你真是个救星啊!:-) - silverdr
1
经过几个小时的搜索,这个解决方案终于起作用了! - TmCrafz

4
在命令行中,将“-i”开关添加到您的ssh命令中:
rsync --progress -rvze "ssh -i/path/to/ssh_private_key" my_user@myserver:/root_folder folder/

@thatotherguy 是的,我知道,那就是我为什么在问的原因。如果你指定脚本应该以 my_user 运行,那么 -i 开关将不再需要。这样会更安全。以 root 用户身份运行命令是不安全的。 - hek2mgl
@hek2mgl 除非您的默认密钥没有密码短语或禁止登录(分别表示不太安全和更麻烦),否则这是必需的。 - that other guy
太完美了,现在它可以工作了!我确实需要使用ssh-keygen -p命令来移除SSH密钥的密码,并选择空密码。 - johncorser
@thatotherguy 这与-i选项无关。(at)johncorser,你可以省略-i选项。 - hek2mgl
@hek2mgl 除非你总是使用默认的私钥文件名(即id_rsa),否则你必须指定-i开关,并且最好在crontab中明确指定密钥文件路径。这只是我的个人建议。 - lihao
显示剩余4条评论

1

另一个选项是让您的 cron 脚本在运行 rsync 之前运行 Keychain

eval $(keychain --agents ssh --eval --noask --quiet)

这假定你已经在另一个终端中以同一用户运行 Keychain,将私钥添加到一个活动的 ssh-agent 进程中:

$ eval $(keychain --agents ssh --eval id_rsa)

 * keychain 2.8.5 ~ http://www.funtoo.org
 * Found existing ssh-agent: 272060
 * Known ssh key: /home/ubuntu/.ssh/id_rsa

运行keychain --list命令以查看当前SSH代理中存在的密钥:

$ keychain --list
3072 SHA256:E2IzZ635kapyGwQG0HiZT+5hCv7dh8glpgvz+qN4dsM ubuntu@raspberrypi1 (RSA)

0

只是为了补充@jytous的答案,通常env|grep -i ssh会给你一个临时文件:

例如:SSH_AUTH_SOCK=/tmp/ssh-1gJufasJLiXv/agent.3591

上面的/tmp指的是一个临时文件,在ssh-agent退出或计算机关机时将被删除。

因此,如果您有运行ssh-agent来管理密钥,请尝试在从cron调用的任何脚本开始处添加以下内容:

auth=`find /tmp -user $LOGNAME -type s -name "*agent*" -print 2>/dev/null`
SSH_AUTH_SOCK=$auth
export SSH_AUTH_SOCK

参考 - 链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接