远程服务器:通过 cronjob 将 rsync 与 ssh 与 gpg 结合使用时,权限被拒绝(公钥)

远程服务器:通过 cronjob 将 rsync 与 ssh 与 gpg 结合使用时,权限被拒绝(公钥)

我想通过 cronjob 定期备份我的远程 VPS。两个系统都运行Debian 10。我一直在关注本指南并根据我的喜好进行了调整。脚本的相关部分:

/root/.local/bin/backup

#!/bin/bash

SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)

rsync -avzAHXh -e ssh root@[someIP]:/path/to/remote/dir /path/to/local/dir \
    || { echo "rsync died with error code $?"; exit 1; }

当我从终端运行它时,一切正常。但是,如果我通过 cronjob 运行它:

crontab -u root -e

# m h  dom mon dow   command
  0 6  *    *    *   /root/.local/bin/backup >> /var/log/backup 2>&1

然后/var/log/backup显示:

root@[someIP]: Permission denied (publickey).^M
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(235) [Receiver=3.1.3]
rsync died with error code 12

cronjob 出了什么问题,我该怎么办?

PS:我已经删除了我在这里使用的 gpg 密钥的密码,试图使其工作。理想情况下,我想要一个即使我再次添加密码短语也能正常工作的解决方案。

答案1

Cron 执行的命令有一个非常基本的执行环境和路径设置,一个常见的错误是用普通用户 ID 来测试命令或脚本。然后由 Cron 运行时就会失败。

导出的环境变量经常被忽视。谨慎的做法是,在部署之前,以 root 身份在完全精简的环境中进行最终测试,使用子 shell。您始终可以添加一个一次性的 cronjob,它只需将其环境打印到日志文件中,这使您能够在 Cron 调用时模拟命令运行的确切条件。第二个优点是,如果发生任何错误,它可以显示在您的终端上,这样更容易调试。

看起来您的脚本中分配的变量未导出,因此 SSH 不会拾取它。

在脚本中使用绝对文件路径也很重要,除非您专门更改目录,否则您不能假设您位于特定目录中,在一次性测试脚本中打印工作目录,前面提到的也有帮助。您不能假设所有分布在这方面都是相同的。检查一下当然没有什么坏处。

相关内容