login时启动ssh-agent

我有一个网站作为远程Git仓库使用SSH别名从Bitbucket.com拉。 我可以在我的服务器上手动启动ssh-agent,但每次通过SSHlogin时都必须这样做。

我手动启动ssh-agent:

eval ssh-agent $SHELL 

然后我添加代理:

 ssh-add ~/.ssh/bitbucket_id 

然后,当我这样做时,它显示出来:

 ssh-add -l 

我很好走。 有什么方法可以自动化这个过程,所以我不必每次login时都这样做。 服务器运行RedHat 6.2(圣地亚哥)。

请阅读这篇文章。 你可能会发现这非常有用:

http://mah.everybody.org/docs/ssh

为了防止上述链接有一天消失,我正在捕获下面的解决scheme的主要部分:

约瑟夫·M·利格(Daniel M. Reagle)通过丹尼尔·斯坦(Daniel Starin)

将以下内容添加到.bash_profile

 SSH_ENV="$HOME/.ssh/environment" function start_agent { echo "Initialising new 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; } # Source SSH settings, if applicable if [ -f "${SSH_ENV}" ]; then . "${SSH_ENV}" > /dev/null #ps ${SSH_AGENT_PID} doesn't work under cywgin ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || { start_agent; } else start_agent; fi 

这个版本特别好,因为它会查看你是否已经启动了ssh-agent,如果找不到它,它会启动并存储设置,以便下次启动贝壳。

接受的解决scheme有以下缺点:

  • 维护起来很复杂;
  • 它会评估可能导致错误或安全漏洞的存储文件;
  • 它启动代理程序,但不会停止,这相当于将钥匙留在点火中。

如果您的密钥不需要input密码,我build议以下解决scheme。 添加以下内容到你的.bash_profile 非常结束 (编辑键列表到您的需要):

 exec ssh-agent $BASH -s 10<&0 << EOF ssh-add ~/.ssh/your_key1.rsa \ ~/.ssh/your_key2.rsa &> /dev/null exec $BASH <&10- EOF 

它具有以下优点:

  • 更简单的解决scheme;
  • 代理会话在bash会话结束时结束。

它有可能的缺点:

  • 交互式的ssh-add命令只会影响一个会话,实际上这只是在非常典型的情况下才是问题。
  • 如果input密码是不可用的;
  • 开始shell变成非login(这不影响任何AFAIK)。

请注意,几个ssh-agent进程不是一个缺点,因为他们不占用更多的内存或CPU时间。

在Arch Linux上,以下工作真的很棒(应该可以在所有基于systemd的发行版上工作):

通过将~/.config/systemd/user/ssh-agent.service放入以下命令创build一个systemd用户服务:

 [Unit] Description=SSH key agent [Service] Type=forking Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket ExecStart=/usr/bin/ssh-agent -a $SSH_AUTH_SOCK [Install] WantedBy=default.target 

设置shell以使套接字具有环境variables( .bash_profile, .zshrc, ... ):

 export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket" 

启用该服务,所以它将在login时自动启动,并启动它:

 systemctl --user enable ssh-agent systemctl --user start ssh-agent 

将下面的configuration设置添加到你的sshconfiguration文件~/.ssh/config (这是从SSH 7.2开始的):

 AddKeysToAgent yes 

这将指示ssh客户端总是将密钥添加到正在运行的代理中,所以不需要事先ssh添加它。

老问题,但我遇到了类似的情况。 不要认为上面的答案完全达到了所需要的。 缺失的是keychain ; 如果还没有安装它。

 sudo apt-get install keychain 

然后~/.bashrc下行添加到~/.bashrc

 eval `keychain --eval id_[yourid file]` 

这将启动ssh-agent如果它没有运行,连接到它,加载ssh-agent环境variables到你的shell,然后加载你的ssh密钥。

参考

https://unix.stackexchange.com/questions/90853/how-can-i-run-ssh-add-automatically-without-password-prompt

把这个添加到你的~/.bashrc

 if [ ! -S ~/.ssh/ssh_auth_sock ]; then eval `ssh-agent` ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock fi export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock ssh-add -l | grep "The agent has no identities" && ssh-add 

这应该只在每次重新启动后第一次login时提示input密码。 只要它保持运行,它将继续重用ssh-agent

所以我习惯使用上面描述的方法,但是当我最后的bash会话结束时,我更喜欢代理死亡。 这比其他解决scheme稍长一点,但它是我的首选方法。 基本的想法是第一个bash会话启动ssh-agent。 然后每个额外的bash会话检查configuration文件( ~/.ssh/.agent_env )。 如果有,并且有一个会话正在运行,则创build一个到/tmp的套接字文件的硬链接(需要与原始套接字文件在同一个文件系统上)。 由于bash会话closures,每个删除自己的硬链接。 最后closures的会话将发现硬链接有2个链接(硬链接和原始链接),删除进程自己的套接字并杀死进程将导致0,在最后的bash会话closures后留下干净的环境。

 # Start ssh-agent to keep you logged in with keys, use `ssh-add` to log in agent=`pgrep ssh-agent -u $USER` # get only your agents if [[ "$agent" == "" || ! -e ~/.ssh/.agent_env ]]; then # if no agents or environment file is missing create a new one # remove old agents / environment variable files kill $agent running rm ~/.ssh/.agent_env # restart eval `ssh-agent` echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ~/.ssh/.agent_env echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ~/.ssh/.agent_env fi # create our own hardlink to the socket (with random name) source ~/.ssh/.agent_env MYSOCK=/tmp/ssh_agent.${RANDOM}.sock ln -T $SSH_AUTH_SOCK $MYSOCK export SSH_AUTH_SOCK=$MYSOCK end_agent() { # if we are the last holder of a hardlink, then kill the agent nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'` if [[ "$nhard" -eq 2 ]]; then rm ~/.ssh/.agent_env ssh-agent -k fi rm $SSH_AUTH_SOCK } trap end_agent EXIT set +x 

对不起,这么晚了:

鱼壳的用户可以使用这个脚本来做同样的事情。

 # content has to be in .config/fish/config.fish # if it does not exist, create the file setenv SSH_ENV $HOME/.ssh/environment function start_agent echo "Initializing new SSH agent ..." ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV echo "succeeded" chmod 600 $SSH_ENV . $SSH_ENV > /dev/null ssh-add end function test_identities ssh-add -l | grep "The agent has no identities" > /dev/null if [ $status -eq 0 ] ssh-add if [ $status -eq 2 ] start_agent end end end if [ -n "$SSH_AGENT_PID" ] ps -ef | grep $SSH_AGENT_PID | grep ssh-agent > /dev/null if [ $status -eq 0 ] test_identities end else if [ -f $SSH_ENV ] . $SSH_ENV > /dev/null end ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep ssh-agent > /dev/null if [ $status -eq 0 ] test_identities else start_agent end end 

我通过将其添加到/ etc / profile – 系统范围(或用户本地.profile或.bash_profile)来解决此问题。

 # SSH-AGENT #!/usr/bin/env bash SERVICE='ssh-agent' WHOAMI=`who am i |awk '{print $1}'` if pgrep -u $WHOAMI $SERVICE >/dev/null then echo $SERVICE running. else echo $SERVICE not running. echo starting ssh-agent > ~/.ssh/agent_env fi . ~/.ssh/agent_env 

这将启动一个新的ssh-agent(如果没有为用户运行),或者在运行时重新设置ssh-agent env参数。

喜欢你的答案很多。 它使从cygwin / linux主机工作更容易。 我结合了开始和结束function,以确保安全。

 SSH_ENV="$HOME/.ssh/.agent_env" function start_agent { echo "Initialising new SSH agent..." eval `/usr/bin/ssh-agent` echo 'export SSH_AUTH_SOCK'=$SSH_AUTH_SOCK >> ${SSH_ENV} echo 'export SSH_AGENT_PID'=$SSH_AGENT_PID >> ${SSH_ENV} echo succeeded chmod 600 "${SSH_ENV}" . "${SSH_ENV}" > /dev/null /usr/bin/ssh-add; } # Source SSH settings, if applicable if [ -f "${SSH_ENV}" ]; then . "${SSH_ENV}" > /dev/null #ps ${SSH_AGENT_PID} doesn't work under cywgin ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || { start_agent; } else start_agent; fi # create our own hardlink to the socket (with random name) MYSOCK=/tmp/ssh_agent.${RANDOM}.sock ln -T $SSH_AUTH_SOCK $MYSOCK export SSH_AUTH_SOCK=$MYSOCK end_agent() { # if we are the last holder of a hardlink, then kill the agent nhard=`ls -l $SSH_AUTH_SOCK | awk '{print $2}'` if [[ "$nhard" -eq 2 ]]; then rm ${SSH_ENV} /usr/bin/ssh-agent -k fi rm $SSH_AUTH_SOCK } trap end_agent EXIT set +x 

再次感谢

为了增加另一个解决scheme:P,我结合了@spheenik和@collin-anderson的解决scheme。

  # Ensure that we have an ssh config with AddKeysToAgent set to true if [ ! -f ~/.ssh/config ] || ! cat ~/.ssh/config | grep AddKeysToAgent | grep yes > /dev/null; then echo "AddKeysToAgent yes" >> ~/.ssh/config fi # Ensure a ssh-agent is running so you only have to enter keys once if [ ! -S ~/.ssh/ssh_auth_sock ]; then eval `ssh-agent` ln -sf "$SSH_AUTH_SOCK" ~/.ssh/ssh_auth_sock fi export SSH_AUTH_SOCK=~/.ssh/ssh_auth_sock 

可能会更优雅,但它简单易读。 此解决scheme:

  • 确保AddKeysToAgent yes在您的sshconfiguration中,因此在使用时会自动添encryption钥
  • 在login时不会提示您input任何密码(同样,首次使用时会出现一次性密码input)
  • 默默地启动一个ssh-agent,如果它还没有启动的话

评论欢迎:)