git 登录时启动 ssh-agent
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18880024/
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
Start ssh-agent on login
提问by Pathsofdesign
I have a site as a remote Git repo pulling from Bitbucket.com using an SSH alias. I can manually start the ssh-agent on my server but I have to do this every time I login via SSH.
我有一个站点作为使用 SSH 别名从 Bitbucket.com 拉取的远程 Git 存储库。我可以在我的服务器上手动启动 ssh-agent,但每次我通过 SSH 登录时都必须这样做。
I manually start the ssh-agent:
我手动启动 ssh-agent:
eval ssh-agent $SHELL
Then I add the agent:
然后我添加代理:
ssh-add ~/.ssh/bitbucket_id
Then it shows up when I do:
然后当我这样做时它会出现:
ssh-add -l
And I'm good to go. Is there any way to automate this process so I don't have to do it every time I login? The server is running RedHat 6.2 (Santiago).
我很高兴去。有什么方法可以使这个过程自动化,这样我就不必每次登录时都这样做吗?服务器运行的是 RedHat 6.2 (Santiago)。
回答by Litmus
Please go through this article. You may find this very useful:
请仔细阅读这篇文章。您可能会发现这非常有用:
http://mah.everybody.org/docs/ssh
http://mah.everybody.org/docs/ssh
Just in case the above link vanishes some day, I am capturing the main piece of the solution below:
以防万一上述链接有一天消失,我正在捕获以下解决方案的主要部分:
This solution from Joseph M. Reagle by way of Daniel Starin:
Add this following to your
.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
This version is especially nice since it will see if you've already started ssh-agent and, if it can't find it, will start it up and store the settings so that they'll be usable the next time you start up a shell.
Joseph 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,如果找不到,将启动它并存储设置,以便您下次启动时可以使用它们贝壳。
回答by spheenik
On Arch Linux, the following works really great (should work on all systemd-based distros):
在 Arch Linux 上,以下效果非常好(应该适用于所有基于 systemd 的发行版):
Create a systemd user service, by putting the following to ~/.config/systemd/user/ssh-agent.service
:
创建一个 systemd 用户服务,将以下内容放入~/.config/systemd/user/ssh-agent.service
:
[Unit]
Description=SSH key agent
[Service]
Type=simple
Environment=SSH_AUTH_SOCK=%t/ssh-agent.socket
ExecStart=/usr/bin/ssh-agent -D -a $SSH_AUTH_SOCK
[Install]
WantedBy=default.target
Setup shell to have an environment variable for the socket (.bash_profile, .zshrc, ...
):
设置 shell 为套接字 ( .bash_profile, .zshrc, ...
)设置一个环境变量:
export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
Enable the service, so it'll be started automatically on login, and start it:
启用该服务,因此它会在登录时自动启动,然后启动它:
systemctl --user enable ssh-agent
systemctl --user start ssh-agent
Add the following configuration setting to your local ssh config file ~/.ssh/config
(this works since SSH 7.2):
将以下配置设置添加到本地 ssh 配置文件~/.ssh/config
(自 SSH 7.2 起有效):
AddKeysToAgent yes
This will instruct the ssh client to always add the key to a running agent, so there's no need to ssh-add it beforehand.
这将指示 ssh 客户端始终将密钥添加到正在运行的代理,因此无需事先 ssh 添加它。
回答by xelber
Old question, but I did come across a similar situation. Don't think the above answer fully achieves what is needed. The missing piece is keychain
; install it if it isn't already.
老问题,但我确实遇到过类似的情况。不要认为上述答案完全达到了需要。缺少的部分是keychain
; 如果尚未安装,请安装它。
sudo apt-get install keychain
Then add the following line to your ~/.bashrc
然后将以下行添加到您的 ~/.bashrc
eval $(keychain --eval id_rsa)
This will start the ssh-agent
if it isn't running, connect to it if it is, load the ssh-agent
environment variables into your shell, and load your ssh key.
ssh-agent
如果它没有运行,这将启动它,如果它正在运行,则连接到它,将ssh-agent
环境变量加载到您的 shell 中,并加载您的 ssh 密钥。
Change id_rsa
to whichever private key in ~/.ssh
you want to load.
更改id_rsa
为~/.ssh
您要加载的任何私钥。
Reference
参考
回答by midenok
The accepted solution have following drawbacks:
公认的解决方案有以下缺点:
- it is complicated to maintain;
- it evaluates storage file which may lead to errors or security breach;
- it starts agent but doesn't stop it which is close equivalent to leaving the key in ignition.
- 维护复杂;
- 评估可能导致错误或安全漏洞的存储文件;
- 它启动代理但不会停止它,这几乎等同于将钥匙留在点火状态。
If your keys do not require to type password, I suggest following solution. Add the following to your .bash_profile
very end(edit key list to your needs):
如果您的密钥不需要输入密码,我建议以下解决方案。将以下内容添加到您的.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
It have following advantages:
它具有以下优点:
- much simpler solution;
- agent session ends when bash session ends.
- 更简单的解决方案;
- 当 bash 会话结束时,代理会话结束。
It have possible disadvantages:
它有可能的缺点:
- interactive
ssh-add
command will influence only one session, which is in fact an issue only in very untypical circumstances; - unusable if typing password is required;
- started shell becomes non-login (which doesn't influence anything AFAIK).
- 交互式
ssh-add
命令只会影响一个会话,这实际上只是在非常不典型的情况下才会出现的问题; - 如果需要输入密码则无法使用;
- 启动的 shell 变为非登录(这不会影响任何 AFAIK)。
Note that several ssh-agent
processes is not a disadvantage, because they don't take more memory or CPU time.
请注意,多个ssh-agent
进程并不是缺点,因为它们不会占用更多内存或 CPU 时间。
回答by Collin Anderson
Add this to your ~/.bashrc
, then logout and back in to take effect.
将此添加到您的~/.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 > /dev/null || ssh-add
This should only prompt for a password the first time you login after each reboot. It will keep reusing the same ssh-agent
as long as it stays running.
这应该只在您每次重新启动后第一次登录时提示输入密码。ssh-agent
只要它保持运行,它就会继续重复使用。
回答by Micah
So I used to use the approaches described above, but I kind of prefer the agent to die when my last bash session ends. This is a bit longer than the other solutions, but its my preferred approach. The basic idea is that the first bash session starts the ssh-agent. Then each additional bash session checks for the config file (~/.ssh/.agent_env
). If that is there and there is a session running then source the environment and create a hardlink to the socket file in /tmp
(needs to be on the same filesystem as the original socket file). As bash sessions shut down each deletes its own hardlink. The last session to close will find that the hardlinks have 2 links (the hardlink and the original), removal of the processes own socket and killing of the process will result in 0, leaving a clean environment after the last bash session closes.
所以我曾经使用上面描述的方法,但我更喜欢代理在我最后一次 bash 会话结束时死亡。这比其他解决方案要长一些,但它是我的首选方法。基本思想是第一个 bash 会话启动 ssh-agent。然后每个额外的 bash 会话检查配置文件 ( ~/.ssh/.agent_env
)。如果存在并且有会话正在运行,则获取环境并创建到套接字文件的硬链接/tmp
(需要与原始套接字文件位于同一文件系统上)。当 bash 会话关闭时,每个会话都会删除自己的硬链接。最后关闭的会话会发现硬链接有2个链接(硬链接和原始链接),删除进程自己的套接字并杀死进程将导致0,在最后一个bash会话关闭后留下一个干净的环境。
# 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 }'`
if [[ "$nhard" -eq 2 ]]; then
rm ~/.ssh/.agent_env
ssh-agent -k
fi
rm $SSH_AUTH_SOCK
}
trap end_agent EXIT
set +x
回答by Keego
Just to add yet another solution :P, I went with a combination of @spheenik and @collin-anderson 's solutions.
只是为了添加另一个解决方案:P,我结合了 @spheenik 和 @collin-anderson 的解决方案。
# 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
Could be a little more elegant but its simple and readable. This solution:
可能更优雅一点,但它简单易读。这个解决方案:
- ensures
AddKeysToAgent yes
is in your ssh config so keys will be automatically added upon use - doesn't prompt you to enter any passphrases at login (again, one-time passphrase entering occurs on first use)
- silently starts an ssh-agent if it has not already started one
- 确保
AddKeysToAgent yes
在您的 ssh 配置中,以便在使用时自动添加密钥 - 登录时不会提示您输入任何密码(同样,第一次使用时会输入一次性密码)
- 如果 ssh-agent 尚未启动,则静默启动
Comments welcome :)
欢迎评论:)
回答by TheFrog
I solved it by adding this to the /etc/profile- system wide (or to user local .profile, or _.bash_profile_):
我通过将它添加到/etc/profile- 系统范围(或用户本地.profile或 _.bash_profile_)来解决它:
# SSH-AGENT
#!/usr/bin/env bash
SERVICE='ssh-agent'
WHOAMI=`who am i |awk '{print }'`
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
This starts a new ssh-agent if not running for the current user, or re-sets the ssh-agent env parameter if running.
如果当前用户没有运行,这将启动一个新的 ssh-agent,或者如果正在运行,则重新设置 ssh-agent env 参数。
回答by Daniel Gerber
Users of the fish shellcan use this scriptto do the same thing.
fish shell 的用户可以使用这个脚本来做同样的事情。
# 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