我经常将数据备份到本地驱动器,然后每天将其同步到远程服务器。
目标服务器配置为仅使用 SSH 密钥(无密码)访问。由于该服务器的主 SSH 密钥受密码保护,因此我创建了第二个 SSH 密钥(不受密码保护)+ 用户,用于无人值守备份- 这样,当 cron 运行时,我就不必在场输入密码。
我正在使用 cron 和 rsync,所有命令单独运行,但组合时失败。
我在故障排除过程中所取得的最大进展就是运行
env -i sh -c "rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/"
返回错误
Permission denied (publickey).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(226) [sender=3.1.0]
关于如何进一步解决此问题有什么提示吗?
这是我到目前为止尝试过的但我没有主意:
- Cron 肯定正在运行
ps aux | grep cron
/var/log/syslog 中没有异常
Sep 7 13:22:01 desktop CRON[6735]: (tom) CMD (sh /home/tom/Documents/Scripts/offsite-backup)
以备份用户身份通过终端通过 SSH 连接到远程服务器
ssh [email protected]
- 在终端中运行命令非常有效
rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
手动指定备份用户密钥的路径无效
rsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /home/tom/.ssh/backups-only' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
用简单的测试命令替换不起作用的命令即可
echo "Hello world" > ~/Desktop/test.txt
对着电脑大喊大叫/咒骂没有效果(但暂时让我感觉好些了)。
编辑1:
这是我的 crontab 文件和它调用的脚本。
...
# m h dom mon dow command
MAILTO=""
* * * * * sh /home/tom/Documents/Scripts/offsite-backup
和
#!/bin/bash
rsync -lrstRO --delete --exclude 'lost+found' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/
编辑2:
需要澄清的是,/var/log/auth.log
目标服务器上包含以下行:Sep 11 08:23:01 <hostname> CRON[24421]: pam_unix(cron:session): session closed for user root
这很令人困惑,因为我不再在本地每分钟运行 cron,但服务器日志中每分钟仍会出现一个新条目。crontab 文件全部服务器上的用户(包括 root)是空的并且不执行任何操作。
此外,仅在服务器上创建了用户“backups-only”,权限有限,专用 SSH 密钥已复制到我的台式机。我认为这是可行的方法,因为手动运行命令时一切都正常。
上面发布的 crontab 文件是为我准备的,我台式机上的用户是“tom”。我的目的是让它调用应该以“backups-only”用户身份登录服务器的脚本。我刚刚尝试运行备份脚本(而不是其中的命令),它成功连接并运行。我以用户“tom”的身份在我的台式机上运行它,这个用户创建了不起作用的 cron 作业。以下是与成功登录相对应的服务器日志的输出
Sep 11 08:35:31 <hostname> sshd[25071]: error: Could not load host key: /etc/ssh/ssh_host_ed25519_key
Sep 11 08:35:32 <hostname> sshd[25071]: Accepted publickey for backups-only from <desktop IP> port 54242 ssh2: RSA e2:e6:07:27:c1:continues...
Sep 11 08:35:32 <hostname> sshd[25071]: pam_unix(sshd:session): session opened for user backups-only by (uid=0)
Sep 11 08:35:32 <hostname> systemd-logind[638]: New session 12 of user backups-only.
Sep 11 08:36:00 <hostname> sshd[25133]: Received disconnect from <desktop IP>: 11: disconnected by user
Sep 11 08:36:00 <hostname> sshd[25071]: pam_unix(sshd:session): session closed for user backups-only
答案1
由于命令行一切正常,错误Permission denied (publickey)
意味着 SSH 部分rsync
使用的身份文件与指定的用户名不同。
从Jan 的评论关于原始问题,我们可以rsync
使用命令指定标识文件-e 'ssh -i /path/to/identity.file' ...
。
使用以下命令在 cron 中启动一个新的环境并指定文件的完整路径显然可以解决问题:
env -i sh -c "rsync -lrstRO --delete --exclude 'lost+found' -e 'ssh -i /home/tom/.ssh/backups-only' /Backups/auto-daily-backups/./ [email protected]:/backups/desktop/"
我仍然对这个发现很感兴趣。这可能与 cron、它以最少的环境变量启动以及 ssh-agent 有关。我将在几天内设置相同的场景来测试它并报告结果。
答案2
我刚刚解决了这个一直困扰着我的问题..
尽管已经规定了 SSH 的身份,但仍无法通过 SSH 连接到 RSYNC...什么也没做... Rsync 说“权限被拒绝”并且 ssh 告诉我“read_passphrase:无法打开 /dev/tty:没有此类型的设备或地址”
但是我读过一篇文章,其中解释说 crontab 有自己的环境,与 root 不同。我已经知道这一点,但我不明白在使用 SSH-AGENT 时它会对 SSH 产生什么影响
但是我的 SSH 密钥交换是通过 PassPhrase 完成的...因此,如果环境不同并且我的 SSH 上的 RSYNC 需要无法输入的密码 => SSH 调试信息也会指示错误:
“debug1:read_passphrase:无法打开/dev/tty:没有这样的设备或地址”=> 是的,没有 TTY = 没有密码 = 不允许
在我的计算机上,我使用“Keychain”启动 SSH 代理,这样我就不必每次尝试远程连接时都重新输入密码。Keychain 生成一个包含以下信息的文件
SSH_AUTH_SOCK = /tmp/ssh-PWg3yHAARGmP/agent.18891; 导出 SSH_AUTH_SOCK; SSH_AGENT_PID = 18893; 导出 SSH_AGENT_PID;
==> SSH-AGENT 命令返回相同的信息。
因此,最终,这些与当前会话相关的信息允许对当前会话进行未来的身份验证,而无需输入密码,因为之前已经完成并记住了......
==> 解决方案就在那里......在 crontab 启动的脚本中就足够了,并且可以“source”包含此信息的文件,或者在命令行 ds crontab 上执行此操作...
例如:14 09 * * *. /home/foo/.keychain/foo.serveur.org-sh && scp -vvv -P 22 /tmp/mon_fic/toto.sh[电子邮件保护]:。>> /var/log/check_connexion.log 2>&1 或者在使用 SSH 启动连接的脚本中使用命令“source /home/foo/keychain/foo.server.org-sh”。
=> 有了这个来源,就不用担心了。SSH_AUTH_SOCK 和 SSH_AGENT_PID 的信息已加载到 Crontab 的环境中,因此已知,SSH 上的 RSYNC 可以正常工作。
它让我很忙,但现在,它起作用了:)
答案3
对于使用 SSH 代理转发的用户请注意:
如果您在远程主机上调试脚本时看到这种行为,那是因为即使有了该-e "ssh -i /path/to/key"
标志,ssh 也会使用您的本地(转发)密钥而不是服务器上的密钥。
具体示例:我在开发服务器上有一个脚本,它使用 rsync 通过 ssh 从“数据服务器”提取数据。当我登录到开发服务器并运行它时,一切都很顺利,但是从 cron 运行时,我被拒绝了权限。在 SSH 进程中添加一些详细内容(标志-vv
)后,我注意到以下情况:
debug2: key: /home/nighty/.ssh/id_rsa (0x562d8b974820),
debug2: key: /home/juanr/.ssh/id_rsa (0x562d8b962930), explicit
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/nighty/.ssh/id_rsa
debug2: we sent a publickey packet, wait for reply
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug2: input_userauth_pk_ok: fp 1a:19:08:9f:80:16:b1:db:55:42:9a:52:b2:49:9b:0a
debug1: Authentication succeeded (publickey).
让我明白的是,纯属偶然,我在本地主机(“nighty”)和开发服务器上的用户名(“juanr”)不同。
请注意,它如何将开发服务器上的密钥标记为“显式”,但仍使用笔记本电脑中转发的密钥登录。ssh-copy-id
此时执行 不会解决任何问题,因为它只是重新安装转发的密钥,而不是开发服务器中的密钥。如果您将 ssh-copy-id 与代理转发一起使用,则需要使用 -i 标志指定要安装哪个密钥:ssh-copy-id -i ~/.ssh/id_rsa.pub user@host
。
答案4
您是否已经尝试过清理 hosts 文件的老办法?我的意思是:
rm ~/.ssh/known_hosts
值得一试,因为 ssh 会重建它,这样你就可以摆脱陈旧的东西。当然,你也可以删除属于给定 IP / 主机的部分。
更多问题:您的 cron 作业是否在您的 UID 下运行,还是以用户 cron 或 root 身份运行?