代码之家  ›  专栏  ›  技术社区  ›  Michael H.

ssh-agent和crontab-有没有一个好的方法来满足这些需求?

  •  27
  • Michael H.  · 技术社区  · 16 年前

    我编写了一个简单的脚本,每晚向开发人员发送SVN活动日志。到目前为止,我在与SVN存储库相同的机器上运行它,所以我不必担心身份验证,我可以只使用SVN的文件:///地址样式。

    现在我在一台家用计算机上运行这个脚本,访问一个远程存储库,所以我不得不改为svn+ssh://paths。通过很好地设置ssh密钥,在正常情况下,我不必输入访问SVN存储库的密码。

    但是,crontab无法访问我的ssh密钥/ssh代理。我在网上读过一些关于这个问题的文章,这里也提到了这个问题,但没有解决:

    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下有效。

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

    10 回复  |  直到 10 年前
        1
  •  21
  •   pra    16 年前

    当您运行ssh agent-s时,它会启动一个后台进程,稍后您需要终止该进程。所以,最起码要把你的黑客行为改成:

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

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

        2
  •  29
  •   Community Mohan Dere    9 年前

    此外。。。

    如果您的密钥具有密码短语,则keychain将询问您一次(有效期至您重新启动计算机或杀死ssh代理)。

    钥匙链就是你需要的!只需安装它并在.bash_配置文件中添加以下代码:

    keychain ~/.ssh/id_dsa
    

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

    . ~/.keychain/$HOSTNAME-sh
    

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

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

        3
  •  7
  •   bryan kennedy    15 年前

    我也有类似的问题。我的脚本(依赖于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现在运行顺利。

        4
  •  6
  •   vpk    14 年前

    恢复运行ssh代理的pid和socket的一种方法是。

    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
    

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

        5
  •  5
  •   Michael Z.    13 年前

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

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

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

        6
  •  3
  •   Dave X    10 年前

    要在不使用自动密码/密码短语黑客的情况下设置自动进程, 我使用一个单独的没有密码的身份文件,并用from=“automated.machine.com”…限制目标计算机的授权密钥条目。等。

    我在.ssh/config中设置了远程自动主机:

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

    以及远程.machine.edu:.ssh/authorized_密钥:

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

    那么ssh不需要ssh代理或keychain提供的外部认证授权。

        7
  •  3
  •   markshep    10 年前

    受这里其他一些答案(尤其是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
    
        8
  •  2
  •   Ivan    12 年前

    假设您已经配置了ssh设置,并且该脚本在终端上运行良好,使用 钥匙链 这绝对是确保脚本在crontab中也能正常工作的最简单方法。

    由于keychain不包括在大多数UNIX/Linux派生中,下面是逐步过程。

    1。 根据您的操作系统版本,从 http://pkgs.repoforge.org/keychain/ .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文件,它们将位于~/.keychain目录中。ID_rsa示例:

    keychain ~/.ssh/id_rsa
    

    4。 在使用ssh身份验证的第一个命令之前,在脚本的任何位置添加以下行:

    source ~/.keychain/$HOSTNAME-sh
    

    我个人试图避免使用额外的程序,但我尝试的所有其他程序都不起作用。这一切都很好。

        9
  •  2
  •   gcbenison    12 年前

    如果您不能使用keychain,并且不能从脚本启动ssh代理(例如,因为您的密钥受密码保护),那么这是一个可以工作的解决方案。

    运行一次:

    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凭据,因此在任何多用户环境中都要小心使用。

        10
  •  1
  •   zevij    10 年前

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

    我也遇到过类似的问题 blogpost 与WayneWalker在博客中提到的shell脚本一样有用。 github .

    祝你好运!

    推荐文章