2010-02-05 73 views
26

我写了一个简单的脚本,每天晚上向开发人员发送svn活动日志。到目前为止,我已经在svn仓库的同一台机器上运行它,所以我不必担心身份验证,我只能使用svn的file:///地址样式。ssh-agent和crontab - 有没有一种很好的方法让这些人见面?

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

但是,crontab没有访问我的ssh-keys/ssh-agent。我读过关于这个问题在网络上几个地方,而且它也提到在这里,没有分辨率:

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

我的解决办法是把它添加到脚本顶部:

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

这似乎在MacOSX 10.6下工作。

我的问题是,这有多糟糕,还有更好的办法吗?

回答

21

当你运行ssh-agent -s时,它启动一个后台进程,你需要稍后终止。因此,最低是你的黑客更改为类似:

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

不过,我不明白这个黑客是如何工作的。只运行代理而不运行ssh-add不会加载任何密钥。也许MacOS的ssh代理的行为与其说的manual page不同。

+0

我很惊讶,但我却认为答案这是在这里: http://serverfault.com/questions/108798/ssh-passphrase-remembered-in-macosx-snow-leopard 我猜这是一个密码的组合存储在系统钥匙串,并添加了ssh-keys直到系统注销。 但这只是一个猜测。感谢您关于杀死cron ssh-agent进程的提示! – khedron 2010-02-05 19:45:30

+0

投票你,因为我有大约十几个ssh-agent进程在后台运行,在我昨晚测试之后。谢谢! – khedron 2010-02-05 19:55:40

8

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

手工定义相应的键与

ssh -i /path/to/key 

没有工作。

但最终我发现,当crontab运行SSH时,SSH_AUTH_SOCK为空。我不知道是什么原因,但我只是

env | grep SSH 

复制的返回值,并将此定义我的crontab的头。

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

我对这里发生的事情没有深入了解,但它解决了我的问题。现在crontab运行平稳。

+0

这为我工作,谢谢! – 2012-04-23 14:00:56

+0

/path/to /键是否带有空密码?如果不需要密码,我认为您不需要使用授权套接字。 – 2016-02-04 15:48:26

+1

注意上面的'/ tmp'。这是指一个临时文件,当'ssh-agent'退出或计算机关闭时将被删除。 – Mikkel 2016-02-15 02:03:55

27

此外...

如果您的密钥有passhphrase,钥匙链会问你一次(有效期至您重新启动计算机或杀死的ssh-agent)。

钥匙扣就是你需要的!只需安装它并在你的代码中添加下面的代码。在.bash_profile:

keychain ~/.ssh/id_dsa 

因此,使用下面的代码在你的脚本加载的ssh-agent环境变量:

. ~/.keychain/$HOSTNAME-sh 

注:钥匙扣也生成代码到csh和鱼类贝壳。从https://serverfault.com/questions/92683/execute-rsync-command-over-ssh-with-an-ssh-agent-via-crontab

+2

钥匙串主页告诉我使用'keychain --noask --eval id_dsa '在为我工作的cron脚本中 - 不确定哪些是最可取的。见http://www.funtoo.org/Keychain – Zitrax 2015-02-02 09:11:01

6

一种方式

复制答案,恢复运行的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 

这当然假定您已经p纤ep安装在系统中,并且只有一个SSH代理运行或多个的情况下,它会采取哪些p纤ep找到最后一个。

4

我的解决方案 - 基于PRA的 - 略有改善,甚至在脚本失败杀死进程:

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

注意,我得叫我的机器(科学版Linux 6)上的ssh-增加。

+0

错误处理!疯狂的想法。 ;-)这看起来很不错,谢谢! – khedron 2013-05-22 15:34:47

1

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

由于钥匙串不包括在大多数的Unix/Linux派生中,下面是一步一步的过程。

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.安装软件包:

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

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

keychain ~/.ssh/id_rsa 

4.以下行添加到您的脚本使用SSH认证的第一个命令之前的任何地方:

source ~/.keychain/$HOSTNAME-sh 

我个人尽量避免使用额外的程序这一点,但我尝试过的其他一切都没有奏效。这工作得很好。

2

这是一个解决方案,如果你不能使用钥匙串,并且你不能从你的脚本启动一个ssh-agent(例如,因为你的密钥是密码保护的),它将起作用。

运行这一次,

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

您是从cron运行脚本:

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

当然,这允许任何人谁可以阅读 '的〜/ .ssh代理文件' 和相应的套接字使用您的ssh证书,因此请谨慎使用任何多用户环境。

+0

另一种方法是设置一个空的密码短语,并在authorized_keys中限制其适用性。 – 2016-02-04 15:59:36

3

要设置没有自动化密码/密码短语的自动化进程,我使用了一个单独的没有密码的IdentityFile,并使用from =“automated.machine.com”等来限制目标机器的authorized_keys条目。

我设立的.ssh/config中一个remoteAuto主持人:

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

,并与remote.machine.edu:.ssh/authorized_keys:

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

然后ssh不需要ssh-agent或keychain提供的外部认证授权。

1

您的解决方案可以正常工作,但每次都会产生一个新的代理程序,正如其他答案已经指出的那样。

我面临类似的问题,我发现这个blogpost很有用,以及Wayne Walker的shell脚本在github的博客中提到。

祝你好运!

3

通过这里的一些其他答案的启发(特别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 
+0

我不得不添加'|因为我的系统由于某种原因重新调用了dup行 – 2016-06-29 23:03:25

+0

我不得不添加'| sed'之前的uniq'排序| uniq',因为两条重复的线不相邻。 – thenickdude 2017-08-30 22:01:22

相关问题