bash ssh-agent 和 crontab —— 有没有什么好办法让它们相遇?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2205282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:55:20  来源:igfitidea点击:

ssh-agent and crontab -- is there a good way to get these to meet?

bashunixcronssh-keys

提问by Michael H.

I wrote a simple script which mails out svn activity logs nightly to our developers. Until now, I've run it on the same machine as the svn repository, so I didn't have to worry about authentication, I could just use svn's file:/// address style.

我写了一个简单的脚本,它每晚将 svn 活动日志邮寄给我们的开发人员。到目前为止,我已经在与 svn 存储库相同的机器上运行它,所以我不必担心身份验证,我可以使用 svn 的 file:/// 地址样式。

Now I'm running the script on a home computer, accessing a remote repository, so I had to change to svn+ssh:// paths. With ssh-key nicely set up, I don't ever have to enter passwords for accessing the svn repository under normal circumstances.

现在我在家用计算机上运行脚本,访问远程存储库,所以我不得不更改为 svn+ssh:// 路径。ssh-key 设置得很好,在正常情况下,我不需要输入密码来访问 svn 存储库。

However, crontab did not have access to my ssh-keys / ssh-agent. I've read about this problem a few places on the web, and it's also alluded to here, without resolution:

但是,crontab 无法访问我的 ssh-keys / ssh-agent。我已经在网上的几个地方读到了这个问题,这里也提到了这个问题,但没有解决:

Why ssh fails from crontab but succedes when executed from a command line?

为什么 ssh 从 crontab 失败,但从命令行执行时成功?

My solution was to add this to the top of the script:

我的解决方案是将其添加到脚本的顶部:

### TOTAL HACK TO MAKE SSH-KEYS WORK  ###
eval `ssh-agent -s`

This seems to work under MacOSX 10.6.

这似乎在 MacOSX 10.6 下工作。

My question is, how terrible is this, and is there a better way?

我的问题是,这有多可怕,有没有更好的方法?

采纳答案by pra

When you run ssh-agent -s, it launches a background process that you'll need to kill later. So, the minimum is to change your hack to something like:

当您运行 ssh-agent -s 时,它会启动一个您稍后需要终止的后台进程。因此,最低限度是将您的 hack 更改为:

eval `ssh-agent -s` 
svn stuff
kill $SSH_AGENT_PID

However, I don't understand how this hack is working. Simply running an agent without also running ssh-add will not load any keys. Perhaps MacOS' ssh-agent is behaving differently than its manual pagesays it does.

但是,我不明白这个 hack 是如何工作的。简单地运行代理而不运行 ssh-add 不会加载任何密钥。也许 MacOS 的 ssh-agent 的行为与其手册页所说的不同。

回答by Mike Hemelberg

In addition...

此外...

If your key have a passhphrase, keychain will ask you once (valid until you reboot the machine or kill the ssh-agent).

如果您的密钥有密码短语,钥匙串将询问您一次(在您重新启动机器或杀死 ssh-agent 之前有效)。

keychain is what you need! Just install it and add the follow code in your .bash_profile:

钥匙扣正是您所需要的!只需安装它并在您的 .bash_profile 中添加以下代码:

keychain ~/.ssh/id_dsa

So use the code below in your script to load the ssh-agent environment variables:

因此,请在脚本中使用以下代码加载 ssh-agent 环境变量:

. ~/.keychain/$HOSTNAME-sh

Note: keychain also generates code to csh and fish shells.

注意:keychain 还会生成 csh 和 fish shell 的代码。

Copied answer from https://serverfault.com/questions/92683/execute-rsync-command-over-ssh-with-an-ssh-agent-via-crontab

https://serverfault.com/questions/92683/execute-rsync-command-over-ssh-with-an-ssh-agent-via-crontab复制答案

回答by bryan kennedy

I had a similar problem. My script (that relied upon ssh keys) worked when I ran it manually but failed when run with crontab.

我有一个类似的问题。我的脚本(依赖于 ssh 密钥)在我手动运行时可以工作,但在使用 crontab 运行时失败。

Manually defining the appropriate key with

手动定义适当的键

ssh -i /path/to/key

didn't work.

没有用。

But eventually I found out that the SSH_AUTH_SOCK was empty when the crontab was running SSH. I wasn't exactly sure why, but I just

但最终我发现当 crontab 运行 SSH 时 SSH_AUTH_SOCK 是空的。我不确定为什么,但我只是

env | grep SSH

copied the returned value and added this definition to the head of my crontab.

复制返回的值并将此定义添加到我的 crontab 的头部。

SSH_AUTH_SOCK="/tmp/value-you-get-from-above-command"

I'm out of depth as to what's happening here, but it fixed my problem. The crontab runs smoothly now.

我对这里发生的事情不了解,但它解决了我的问题。crontab 现在运行顺利。

回答by vpk

One way to recover the pid and socket of running ssh-agent would be.

恢复运行 ssh-agent 的 pid 和套接字的一种方法是。

SSH_AGENT_PID=`pgrep -U $USER ssh-agent`
for PID in $SSH_AGENT_PID; do
    let "FPID = $PID - 1"
    FILE=`find /tmp -path "*ssh*" -type s -iname "agent.$FPID"`
    export SSH_AGENT_PID="$PID" 
    export SSH_AUTH_SOCK="$FILE"
done

This of course presumes that you have pgrep installed in the system and there is only one ssh-agent running or in case of multiple ones it will take the one which pgrep finds last.

这当然假设您在系统中安装了 pgrep 并且只有一个 ssh-agent 在运行,或者在多个 ssh-agent 的情况下,它将采用 pgrep 最后找到的那个。

回答by Michael Z.

My solution - based on pra's - slightly improved to kill process even on script failure:

我的解决方案 - 基于 pra 的 - 即使在脚本失败时也略有改进以终止进程:

eval `ssh-agent`
function cleanup {
    /bin/kill $SSH_AGENT_PID
}
trap cleanup EXIT
ssh-add
svn-stuff

Note that I must call ssh-add on my machine (scientific linux 6).

请注意,我必须在我的机器上调用 ssh-add(scientific linux 6)。

回答by Ivan

Assuming that you already configured SSH settings and that script works fine from terminal, using the keychainis definitely the easiest way to ensure that script works fine in crontab as well.

假设您已经配置了 SSH 设置并且该脚本在终端上正常工作,那么使用钥匙串绝对是确保脚本在 crontab 中也能正常工作的最简单方法。

Since keychain is not included in most of Unix/Linux derivations, here is the step by step procedure.

由于大多数 Unix/Linux 衍生版本中不包含钥匙串,因此这里是分步过程。

1.Download the appropriate rpm package depending on your OS version from http://pkgs.repoforge.org/keychain/. Example for CentOS 6:

1.根据您的操作系统版本从http://pkgs.repoforge.org/keychain/下载适当的 rpm 包。CentOS 6 的示例:

wget http://pkgs.repoforge.org/keychain/keychain-2.7.0-1.el6.rf.noarch.rpm

2.Install the package:

2.安装包:

sudo rpm -Uvh keychain-2.7.0-1.el6.rf.noarch.rpm

3.Generate keychain files for your SSH key, they will be located in ~/.keychain directory. Example for id_rsa:

3.为您的 SSH 密钥生成钥匙串文件,它们将位于 ~/.keychain 目录中。id_rsa 示例:

keychain ~/.ssh/id_rsa

4.Add the following line to your script anywhere before the first command that is using SSH authentication:

4.将以下行添加到脚本中使用 SSH 身份验证的第一个命令之前的任何位置:

source ~/.keychain/$HOSTNAME-sh

I personally tried to avoid to use additional programs for this, but everything else I tried didn't work. And this worked just fine.

我个人试图避免为此使用其他程序,但我尝试过的其他一切都不起作用。这工作得很好。

回答by Dave X

To set up automated processes without automated password/passphrase hacks, I use a separate IdentityFile that has no passphrase, and restrict the target machines' authorized_keys entries prefixed with from="automated.machine.com" ...etc..

为了设置没有自动密码/密码破解的自动化流程,我使用了一个没有密码的单独 IdentityFile,并限制了目标机器的authorized_keys 条目以 etc. 为前缀from="automated.machine.com" ...

I created a public-private keyset for the sending machine without a passphrase:

我为没有密码的发送机器创建了一个公私密钥集:

ssh-keygen -f .ssh/id_localAuto

(Hit return when prompted for a passphrase)

(提示输入密码时按回车键)

I set up a remoteAuto Host entry in .ssh/config:

我在以下位置设置了一个 remoteAuto Host 条目.ssh/config

Host remoteAuto
    HostName remote.machine.edu
    IdentityFile  ~/.ssh/id_localAuto

and the remote.machine.edu:.ssh/authorized_keys with:

和 remote.machine.edu:.ssh/authorized_keys 与:

...
from="192.168.1.777" ssh-rsa ABCDEFGabcdefg....
...

Then ssh doesn't need the externally authenticated authorization provided by ssh-agent or keychain, so you can use commands like:

然后 ssh 不需要 ssh-agent 或 keychain 提供的外部验证授权,因此您可以使用以下命令:

scp -p remoteAuto:watchdog ./watchdog_remote
rsync -Ca remoteAuto/stuff/* remote_mirror
svn svn+ssh://remoteAuto/path
svn update
... 

回答by markshep

Inspired by some of the other answers here (particularly vpk's) I came up with the following crontab entry, which doesn't require an external script:

受到这里其他一些答案(特别是 vpk 的)的启发,我想出了以下 crontab 条目,它不需要外部脚本:

PATH=/usr/bin:/bin:/usr/sbin:/sbin

* * * * *   SSH_AUTH_SOCK=$(lsof -a -p $(pgrep ssh-agent) -U -F n | sed -n 's/^n//p') ssh hostname remote-command-here

回答by zevij

Your solution works but it will spawn a new agent process every time as already indicated by some other answer.

您的解决方案有效,但它每次都会产生一个新的代理进程,正如其他一些答案所指示的那样。

I faced similar issues and I found this blogpostuseful as well as the shell script by Wayne Walker mentioned in the blog on github.

我面临着类似的问题,我发现这个博客帖子有用以及外壳由韦恩·沃克脚本在博客中提到github上

Good luck!

祝你好运!

回答by gcbenison

Here is a solution that will work if you can't use keychain and if you can't start an ssh-agent from your script (for example, because your key is passphrase-protected).

如果您无法使用钥匙串并且无法从脚本启动 ssh-agent(例如,因为您的密钥受密码保护),这里有一个解决方案。

Run this once:

运行一次:

nohup ssh-agent > .ssh-agent-file &
. ssh-agent-file
ssh-add  # you'd enter your passphrase here

In the script you are running from cron:

在您从 cron 运行的脚本中:

# start of script
. ${HOME}/.ssh-agent-file
# now your key is available

Of course this allows anyone who can read '~/.ssh-agent-file' and the corresponding socket to use your ssh credentials, so use with caution in any multi-user environment.

当然,这允许任何可以读取 '~/.ssh-agent-file' 和相应套接字的人使用您的 ssh 凭据,因此在任何多用户环境中谨慎使用。