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

ssh 权限仅在 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-agent),这就是为什么它在脚本中失败,但在从 bash 会话运行时却不会失败的原因。添加. ~/.keychain/$HOSTNAME-sh到我的脚本解决了这个问题(感谢 @grawity 为我指明了正确的方向并提供了全面的答案)。

答案1

交互式命令和 cron 任务在不同的环境中运行 - 特别是,交互式会话可能正在运行 SSH 代理,或者存储 Kerberos TGT。由于ssh订单验证方式,您不能确保您的密钥能够被使用,因为您添加了该-i选项。

  • 如果 SSH 代理正在运行,ssh客户端将始终尝试代理密钥使用任何明确指定的键。

  • 如果网络使用 Kerberos 并且存在 Kerberos TGT,则 OpenSSH 将使用它尝试公钥认证。

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

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

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

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

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


如果你添加从 cron 访问代理的提示 - 那就更好了

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

你提到了“Keychain”——这是 OS X 程序,还是 Linux 脚本?(我不太了解 Mac OS X 的架构,但据我所知,它使它很多从 cronjob 访问用户的 ssh-agent 更加困难……)

答案2

解决此问题的另一个方法是将 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

答案3

您可以使用ssh-cron设置计划的 SSH 连接以保护服务器,而无需暴露您的 SSH 密钥,而是使用 SSH 代理。

答案4

您可以在 crontab 中运行脚本或命令,例如:

0 * * * * bash -c -l “/home/user/sshscript.sh”

或者

0 * * * * bash -c -l “ssh root@yourhost‘echo $HOSTNAME’”

相关内容