我有一个bash脚本,它对远程机器执行ssh并在那里执行命令,如:
ssh -nxv user@remotehost echo "hello world"
当我从命令行执行命令时,它工作正常,但在作为crontab的一部分执行时失败(errorcode = 255 - 无法建立SSH连接)。详细说明:
...
Waiting for server public key.
Received server public key and host key.
Host 'remotehost' is known and matches the XXX host key.
...
Remote: Your host key cannot be verified: unknown or invalid host key.
Server refused our host key.
Trying XXX authentication with key '...'
Server refused our key.
...
在本地执行时,我充当root用户,crontab也以root身份运行。 从crontab和命令行执行'id'会得到完全相同的结果:
$ id
> uid=0(root) gid=0(root) groups=0(root),...
我从一些本地机器ssh到运行crond的机器。我有ssh密钥和凭据ssh到crond机器和脚本连接的任何其他机器。
PS。请不要问/抱怨/评论以root身份执行任何错误/错误/等等 - 这不是这个问题的目的。
答案 0 :(得分:25)
keychain
以无痛的方式解决这个问题。它在Debian / Ubuntu的回购中:
sudo apt-get install keychain
也许对于许多其他发行版(看起来它起源于Gentoo)。
如果没有正在运行,此程序将启动ssh-agent
,并提供可source
d的shell脚本,并将当前shell连接到此特定ssh-agent
。
对于bash
,使用名为id_rsa
的私钥,将以下内容添加到.profile
:
keychain --nogui id_rsa
这将启动ssh-agent
并在重新启动后首次登录时添加id_rsa
密钥。如果密钥受密码保护,它也会要求密码短语。 不再需要使用不受保护的密钥了!对于后续登录,它会识别代理,而不是再次要求密码。
另外,请将以下内容添加为.bashrc
的最后一行:
. ~/.keychain/$HOSTNAME-sh
这将让shell知道到达keychain
管理的SSH代理的位置。确保.bashrc
来自.profile
。
但是,cron
工作似乎仍然没有看到这一点。作为补救措施,请在实际命令之前的crontab
中包含上述行:
* * * * * . ~/.keychain/$HOSTNAME-sh; your-actual-command
答案 1 :(得分:9)
我猜通常当你从本地机器ssh到运行crond的机器时,你的私钥被加载到ssh-agent中并通过连接转发。因此,当您从命令行执行命令时,它会在ssh-agent中找到您的私钥,并使用它来登录远程计算机。
当crond执行命令时,它无法访问ssh-agent,因此无法使用您的私钥。
您必须在运行crond的计算机上为root创建一个新的私钥,并将其公共部分复制到您希望crond登录的远程计算机上的相应authorized_keys
文件中。 / p>
答案 2 :(得分:4)
不要在没有密码短语的情况下公开SSH密钥。请改用ssh-cron,这允许您使用SSH代理安排任务。
答案 3 :(得分:1)
所以我遇到了类似的问题。我来到这里并看到了各种答案,但这里有一些实验是我如何使用密码短语,ssh-agent和cron的sshkeys。
首先,我的ssh安装程序在我的bash init脚本中使用以下脚本。
# JFD Added this for ssh
SSH_ENV=$HOME/.ssh/environment
# start the ssh-agent
function start_agent {
echo "Initializing new SSH agent..."
# spawn ssh-agent
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
echo succeeded
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
/usr/bin/ssh-add
}
if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
当我登录时,我输入一次密码,然后从那时起,它将使用ssh-agent自动验证我。
ssh-agent详细信息保存在.ssh / environment中。这是脚本的样子:
SSH_AUTH_SOCK=/tmp/ssh-v3Tbd2Hjw3n9/agent.2089; export SSH_AUTH_SOCK;
SSH_AGENT_PID=2091; export SSH_AGENT_PID;
#echo Agent pid 2091;
关于cron,您可以通过各种方式将作业设置为普通用户。 如果以root用户身份运行crontab -e,它将设置root用户cron。如果你以crontab -u davis -e运行,它将添加一个cron作为userid davis。同样,如果您以用户davis身份运行并执行crontab -e,它将创建一个以userid davis身份运行的cron作业。这可以通过以下条目进行验证:
30 * * * * /usr/bin/whoami
这将每30分钟将whoami的结果邮寄给用户davis。 (我做了一个crontabe -e作为用户davis。)
如果您尝试查看用户davis使用的键,请执行以下操作:
36 * * * * /usr/bin/ssh-add -l
它会失败,邮件发送的日志会说
To: davis@xxxx.net
Subject: Cron <davis@hostyyy> /usr/bin/ssh-add -l
Could not open a connection to your authentication agent.
解决方案是为上面的ssh-agent提供env脚本。以下是生成的cron条目:
55 10 * * * . /home/davis/.ssh/environment; /home/davis/bin/domythingwhichusesgit.sh
这将在10:55运行脚本。注意领先。在脚本中。它表示在我的环境中运行此脚本,类似于.bash init脚本中的脚本。
答案 4 :(得分:-3)
昨天我遇到了类似的问题...
我在一台服务器上有cron作业,它使用ssh在其他服务器上启动一些操作...问题是用户权限和密钥......
在crontab我有
* * * * * php /path/to/script/doSomeJob.php
它根本不起作用(没有权限)。 我尝试将cron作为特定用户运行,该用户连接到其他服务器
* * * * * user php /path/to/script/doSomeJob.php
但没有效果。
最后,我导航到脚本,然后执行php文件,它工作..
* * * * * cd /path/to/script/; php doSomeJob.php