ssh 权限仅在 cron 作业中被拒绝

Yoa*_*ner 16 ssh bash cron

有一个非常奇怪的问题。我创建了一个小的 bash 脚本,它通过 ssh(使用公钥身份验证)在远程主机上运行命令。

当我从命令行手动运行此脚本时,它工作正常,但是当放置在 /etc/cron.hourly 中时,它会失败并显示Permission denied, please try again.错误。

  • 我使用ssh -i /root/.ssh/id_rsa user@remote "command";在脚本中显式设置密钥
  • 脚本以 root 身份运行(我添加了一个echo `id` > /tmp/whoami.log来仔细检查);和
  • ssh 密钥没有密码保护...

系统是 Ubuntu 12.04 服务器,我在远程端没有太多访问权限进行故障排除,但正如我所说,手动运行 ssh 或从命令行运行相同的 bash 脚本。

知道为什么会发生这种情况或如何解决吗?

更新

结果我弄错了,ssh 密钥密码保护(钥匙串加载 ssh 代理),因此为什么它从脚本中失败,但在从 bash 会话运行时却没有。添加. ~/.keychain/$HOSTNAME-sh到我的脚本中解决了问题(感谢@grawity 为我指明了正确的方向并提供了全面的答案)。

use*_*686 11

交互式命令和 cron 作业在不同的环境中运行——特别是,交互式会话可能会运行 SSH 代理或存储 Kerberos TGT。由于ssh订购身份验证方法的方式,您不能仅仅因为添加了-i选项就确定使用了您的密钥。

  • 如果 SSH 代理正在运行,ssh客户端总是使用任何明确指定的密钥之前尝试代理密钥。

  • 如果网络使用 Kerberos 并且存在 Kerberos TGT,OpenSSH 将尝试公钥身份验证之前使用它。

我对您的环境一无所知,但这两种可能性都很容易检查:

  1. 在命令之前添加unset SSH_AUTH_SOCK和,然后手动运行修改后的脚本。unset KRB5CCNAMEssh

    这将防止脚本看到代理或 Kerberos 票证,并且只会使用明确指定的密钥。

  2. -v选项添加到ssh. 这将显示有关如何进行身份验证的更多详细信息。

您也可以添加-oIdentitiesOnly=yesssh命令中;这将强制它使用指定的 key


如果您添加有关从 cron 访问代理的提示 - 甚至更好

通常不建议这样做,因为代理通常与您的交互式登录会话密切相关。特别是,它仅在您登录时启动,并在您注销时终止——它需要您的密码才能真正解锁 SSH 密钥(假设它们受密码保护)。

你提到了“钥匙串”——这是 OS X 程序还是 Linux 脚本?(我不太了解 Mac OS X 的架构,但 AFAIK 使得从 cronjob 访问用户的 ssh-agent变得更加困难......)


小智 5

此问题的另一个解决方法是将 cron 设置为 ssh 到本地框,以依次运行 ssh 命令,而不是通过其本地绝对路径运行文件或命令。这会缓存 KRB5CCNAME 并在 /path/command 没有的地方工作。

# Fails:
0 * * * * /home/user/sshscript.sh

# Works:
0 * * * * /usr/bin/ssh user@localhost /home/user/sshscript.sh

#!/bin/bash
# Works:
unset SSH_AUTH_SOCK
unset KRB5CCNAME
/usr/bin/ssh user@localhost /home/user/sshscript.sh
Run Code Online (Sandbox Code Playgroud)