http://blog.joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add/
很多时候我们要使用我们的私钥的时候,我们都需要输入我们的密码,然后才能正常的使用私钥去登陆远程主机,去git pull我们的repo, 去干一些事,但是,我们并不想每一次都输入(安全原因咱是不考虑),有没有办法能让我们输入一次,在一段时间内(或者重启),都免于再次如入我们密钥的密码?答案是肯定的,那就是我们常用的ssh-agent 和ssh-add
ssh-agent
从这个agent我们就知道这是一个代理,代理什么呢?代理我们的私钥,这个ssh-agent可以在我们的后台运行,然后我们可以通过ssh-add将我们的key加入到后台运行的ssh-agent中,这样,我们就可以使用我们的key并且不需要每次都输入密码了,如何启动呢?
我们可以在我们的.bashrc中添加如下代码:
eval $(ssh-agent) > /dev/null
1 |
但是这有一个问题,问题就是每次打开我们的shell,我们都会创建一个心的ssh-agent,久而久之我们就有好多个ssh-agent在跑了,并且每次启动一个新的,我们都需要通过ssh-add来添加我们的key,这并不是我们想要的
让我们先来看一下ssh-agent是如何工作的:
1 2 3 4 |
$ssh-agent SSH_AUTH_SOCK=/tmp/ssh-sp4EAi4iNWF5/agent.26520; export SSH_AUTH_SOCK; SSH_AGENT_PID=26521; export SSH_AGENT_PID; echo Agent pid 26521; |
1 2 3 4 |
ps x | grep ssh-agent 21983 ? Ss 0:00 ssh-agent 26521 ? Ss 0:00 ssh-agent 26540 pts/5 S+ 0:00 grep --color=auto ssh-agent |
我们可以从第一个命令中得到$SSH_AUTH_SOCK
and $SSH_AGENT_PID
.
其中,$SSH_AGENT_PID 这个就是ssh-agent的id,我们可以通过ssh-agent -k $SSH_AGENT_PID 来干掉它
非常重要的环境变量是$SSH_AUTH_SOCK, 这个环境变量非常重要,如果这个变量有问题,你无法使用ssh-add命令来添加私钥
我们也可以在多个shell中使用同一个ssh-agent, 但是我们需要手动设定环境变量$SSH_AUTH_SOCK
好在有个人已经写好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# Copyright (C) 2011 by Wayne Walker <wwalker@solid-constructs.com> # # Released under one of the versions of the MIT License. # # Copyright (C) 2011 by Wayne Walker <wwalker@solid-constructs.com> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. _LIVE_AGENT_LIST="" declare -a _LIVE_AGENT_SOCK_LIST _LIVE_AGENT_SOCK_LIST=() _debug_print() { if [[ $_DEBUG -gt 0 ]] then printf "%s\n" $1 fi } find_all_ssh_agent_sockets() { _SSH_AGENT_SOCKETS=`find /tmp/ -type s -name agent.\* 2> /dev/null | grep '/tmp/ssh-.*/agent.*'` _debug_print "$_SSH_AGENT_SOCKETS" } find_all_gpg_agent_sockets() { _GPG_AGENT_SOCKETS=`find /tmp/ -type s -name S.gpg-agent.ssh 2> /dev/null | grep '/tmp/gpg-.*/S.gpg-agent.ssh'` _debug_print "$_GPG_AGENT_SOCKETS" } find_all_gnome_keyring_agent_sockets() { _GNOME_KEYRING_AGENT_SOCKETS=`find /tmp/ -type s -name ssh 2> /dev/null | grep '/tmp/keyring-.*/ssh$'` _debug_print "$_GNOME_KEYRING_AGENT_SOCKETS" } find_all_osx_keychain_agent_sockets() { [[ -n "$TMPDIR" ]] || TMPDIR=/tmp _OSX_KEYCHAIN_AGENT_SOCKETS=`find $TMPDIR/ -type s -regex '.*/ssh-.*/agent..*$' 2> /dev/null` _debug_print "$_OSX_KEYCHAIN_AGENT_SOCKETS" } test_agent_socket() { local SOCKET=$1 SSH_AUTH_SOCK=$SOCKET ssh-add -l 2> /dev/null > /dev/null result=$? _debug_print $result if [[ $result -eq 0 ]] then # contactible and has keys loaded _KEY_COUNT=`SSH_AUTH_SOCK=$SOCKET ssh-add -l | wc -l | tr -d ' '` fi if [[ $result -eq 1 ]] then # contactible butno keys loaded _KEY_COUNT=0 fi if [[ ( ( $result -eq 0 ) || ( $result -eq 1 ) ) ]] then if [[ -n "$_LIVE_AGENT_LIST" ]] then _LIVE_AGENT_LIST="${_LIVE_AGENT_LIST} ${SOCKET}:$_KEY_COUNT" else _LIVE_AGENT_LIST="${SOCKET}:$_KEY_COUNT" fi return 0 fi return 1 } find_live_gnome_keyring_agents() { for i in $_GNOME_KEYRING_AGENT_SOCKETS do test_agent_socket $i done } find_live_osx_keychain_agents() { for i in $_OSX_KEYCHAIN_AGENT_SOCKETS do test_agent_socket $i done } find_live_gpg_agents() { for i in $_GPG_AGENT_SOCKETS do test_agent_socket $i done } find_live_ssh_agents() { for i in $_SSH_AGENT_SOCKETS do test_agent_socket $i done } function fingerprints() { local file="$1" while read l; do [[ -n $l && ${l###} = $l ]] && ssh-keygen -l -f /dev/stdin <<<$l done < $file } find_all_agent_sockets() { _SHOW_IDENTITY=0 if [ "$1" = "-i" ] ; then _SHOW_IDENTITY=1 fi _LIVE_AGENT_LIST= find_all_ssh_agent_sockets find_all_gpg_agent_sockets find_all_gnome_keyring_agent_sockets find_all_osx_keychain_agent_sockets find_live_ssh_agents find_live_gpg_agents find_live_gnome_keyring_agents find_live_osx_keychain_agents _debug_print "$_LIVE_AGENT_LIST" _LIVE_AGENT_LIST=$(echo $_LIVE_AGENT_LIST | tr ' ' '\n' | sort -n -t: -k 2 -k 1 | uniq) _LIVE_AGENT_SOCK_LIST=() _debug_print "SORTED: $_LIVE_AGENT_LIST" _FINGERPRINTS=$(fingerprints ~/.ssh/authorized_keys) if [[ $_SHOW_IDENTITY -gt 0 ]] then i=0 for a in $_LIVE_AGENT_LIST ; do sock=${a/:*/} _LIVE_AGENT_SOCK_LIST[$i]=$sock # technically we could have multiple keys forwarded # But I haven't seen anyone do it akeys=$(SSH_AUTH_SOCK=$sock ssh-add -l) key_size=$(echo ${akeys} | awk '{print $1}') fingerprint=$(echo ${akeys} | awk '{print $2}') remote_name=$(echo ${akeys} | awk '{print $3}') authorized_entry=$(fingerprints ~/.ssh/authorized_keys | grep $fingerprint) comment=$(echo ${authorized_entry} | awk '{print $3,$4,$5,$6,$7}') printf "export SSH_AUTH_SOCK=%s \t#%i) \t%s\n" "$sock" $((i+1)) "$comment" i=$((i+1)) done else printf "%s\n" "$_LIVE_AGENT_LIST" | sed -e 's/ /\n/g' | sort -n -t: -k 2 -k 1 fi } set_ssh_agent_socket() { if [ "$1" = "-c" -o "$1" = "--choose" ] then find_all_agent_sockets -i if [ -z "$_LIVE_AGENT_LIST" ] ; then echo "No agents found" return 1 fi echo -n "Choose (1-${#_LIVE_AGENT_SOCK_LIST[@]})? " read choice if [ -n "$choice" ] then n=$((choice-1)) if [ -z "${_LIVE_AGENT_SOCK_LIST[$n]}" ] ; then echo "Invalid choice" return 1 fi echo "Setting export SSH_AUTH_SOCK=${_LIVE_AGENT_SOCK_LIST[$n]}" export SSH_AUTH_SOCK=${_LIVE_AGENT_SOCK_LIST[$n]} fi else # Choose the first available SOCK=$(find_all_agent_sockets|tail -n 1|awk -F: '{print $1}') if [ -z "$SOCK" ] ; then return 1 fi export SSH_AUTH_SOCK=$SOCK fi return 0 } ssh-find-agent() { if [ "$1" = "-c" -o "$1" = "--choose" ] then set_ssh_agent_socket -c return $? elif [ "$1" = "-a" -o "$1" = "--auto" ] then set_ssh_agent_socket return $? else find_all_agent_sockets -i return 0 fi } |
这个保存为:.ssh-find-agent
然后编辑我们的.bashrc
加入下面两行:
1 2 |
source ~/.ssh-find-agent set_ssh_agent_socket |
这样我们就不会每次都创建新的ssh-agent了
Latest posts by Zhiming Zhang (see all)
- aws eks node 自动化扩展工具 Karpenter - 8月 10, 2022
- ReplicationController and ReplicaSet in Kubernetes - 12月 20, 2021
- public key fingerprint - 5月 27, 2021
lcgogo 2018/08/24 11:10
都会创建一个心的. 应该是新的 eval $(ssh-agent) > /dev/null。应该放入代码框