有没有一种方便的方法可以确保来自给定用户(即我)的所有登录都使用相同的 ssh 代理?我编写了一个脚本,使它在大多数情况下都能正常工作,但我一直怀疑有某种方法可以做到这一点,而我却错过了。此外,从那时起,计算技术取得了惊人的进步,例如这个网站。
所以这里的目标是
- 每当我登录到该框时,无论是通过 SSH,还是通过从 gdm/kdm/etc 启动的图形会话,还是在控制台:
- 如果我的用户名当前没有
ssh-agent
运行,则启动一个,导出环境变量并ssh-add
调用。 - 否则,现有代理的坐标将导出到登录会话的环境变量中。
- 如果我的用户名当前没有
当该盒子被用作进入第三个盒子的中继点时,此功能尤其有用。ssh
在这种情况下,它避免了每次你通过 ssh 进入然后想要执行git push
某些操作时都必须输入私钥的密码。
下面给出的脚本可以可靠地完成此操作,尽管最近 X 崩溃时它出现了问题,然后我又启动了另一个图形会话。那个实例中可能还发生了其他问题。
这是我的坏即是好脚本。我从我的 中获取了此脚本.bashrc
。
# ssh-agent-procure.bash
# v0.6.4
# ensures that all shells sourcing this file in profile/rc scripts use the same ssh-agent.
# copyright me, now; licensed under the DWTFYWT license.
mkdir -p "$HOME/etc/ssh";
function ssh-procure-launch-agent {
eval `ssh-agent -s -a ~/etc/ssh/ssh-agent-socket`;
ssh-add;
}
if [ ! $SSH_AGENT_PID ]; then
if [ -e ~/etc/ssh/ssh-agent-socket ] ; then
SSH_AGENT_PID=`ps -fC ssh-agent |grep 'etc/ssh/ssh-agent-socket' |sed -r 's/^\S+\s+(\S+).*$/\1/'`;
if [[ $SSH_AGENT_PID =~ [0-9]+ ]]; then
# in this case the agent has already been launched and we are just attaching to it.
##++ It should check that this pid is actually active & belongs to an ssh instance
export SSH_AGENT_PID;
SSH_AUTH_SOCK=~/etc/ssh/ssh-agent-socket; export SSH_AUTH_SOCK;
else
# in this case there is no agent running, so the socket file is left over from a graceless agent termination.
rm ~/etc/ssh/ssh-agent-socket;
ssh-procure-launch-agent;
fi;
else
ssh-procure-launch-agent;
fi;
fi;
请告诉我有更好的方法。另外,请不要挑剔不一致之处/失误之处(例如放入var
东西etc
);我不久前写了这篇文章,从那时起学到了很多东西。
答案1
我也可以把自己的变化加入进来:
function sshagent_findsockets {
find /tmp -uid $(id -u) -type s -name agent.\* 2>/dev/null
}
function sshagent_testsocket {
if [ ! -x "$(which ssh-add)" ] ; then
echo "ssh-add is not available; agent testing aborted"
return 1
fi
if [ X"$1" != X ] ; then
export SSH_AUTH_SOCK=$1
fi
if [ X"$SSH_AUTH_SOCK" = X ] ; then
return 2
fi
if [ -S $SSH_AUTH_SOCK ] ; then
ssh-add -l > /dev/null
if [ $? = 2 ] ; then
echo "Socket $SSH_AUTH_SOCK is dead! Deleting!"
rm -f $SSH_AUTH_SOCK
return 4
else
echo "Found ssh-agent $SSH_AUTH_SOCK"
return 0
fi
else
echo "$SSH_AUTH_SOCK is not a socket!"
return 3
fi
}
function sshagent_init {
# ssh agent sockets can be attached to a ssh daemon process or an
# ssh-agent process.
AGENTFOUND=0
# Attempt to find and use the ssh-agent in the current environment
if sshagent_testsocket ; then AGENTFOUND=1 ; fi
# If there is no agent in the environment, search /tmp for
# possible agents to reuse before starting a fresh ssh-agent
# process.
if [ $AGENTFOUND = 0 ] ; then
for agentsocket in $(sshagent_findsockets) ; do
if [ $AGENTFOUND != 0 ] ; then break ; fi
if sshagent_testsocket $agentsocket ; then AGENTFOUND=1 ; fi
done
fi
# If at this point we still haven't located an agent, it's time to
# start a new one
if [ $AGENTFOUND = 0 ] ; then
eval `ssh-agent`
fi
# Clean up
unset AGENTFOUND
unset agentsocket
# Finally, show what keys are currently in the agent
ssh-add -l
}
alias sagent="sshagent_init"
然后每次我登录时,如果我想附加代理(我并不总是这样做),我只需输入sagent
。
答案2
ssh -A [user@]remotehost
我认为这可能就是您要找的东西。运行 ssh 时使用 -A 开关转发您的 ssh-agent。这是一个用例:
我有一个远程服务器,上面有一些 git repos,远程指向 github。如果没有在屏幕会话中运行 ssh-agent,我必须输入密钥的密码才能执行“git pull origin master”。嘘!此外,我必须有我的私人的安装在远程服务器上的密钥 - 更多Boooo!
相反,只需使用ssh -A [user@]remotehost
本地运行的 ssh-agent 即可。现在,我不再需要我的私钥存在于远程主机上。我认为您根本不需要使用 ssh-agent 编写任何脚本。
答案3
这是一个非常好的,在 Cygwin 中也可以运行:
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 -efp ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
将其添加到你的 .bash_profile 或 .bashrc
答案4
我最近开始使用:
https://github.com/ccontavalli/ssh-ident
我所要做的就是添加:
alias ssh=/path/to/ssh-ident
在我的 .bashrc 文件中。该脚本负责:
- 首次需要时创建代理
- 按需加载必要的密钥
- 在多个登录会话之间共享代理
- 管理多个代理,每个代理对应我在线使用的每个“身份”,并根据我连接的主机或当前工作目录使用正确的代理。