密钥创建的时候,是可以选择将passphrase置空,也就是免输入passphrase,直接登录到SSH服务端,但这样做会破坏密钥的安全性,强烈不推荐.一般只在用于无人工干预的自动化任务执行时会用空passphrase的密钥.
但是,如果启用了passphrase,每次登录到远端服务器,都需要敲一遍passphrase,过程比较繁琐.OpenSSH提供了ssh-agent用于解决这个问题.
使用了ssh-agent之后,可以将私钥托管给ssh-agent,只在添加这个托管的时候输入一次passphrase,ssh-agent会加载这个私钥到内存中,后续可以在当前会话任意次免输入passphrase登录到基于这个密钥认证的SSH服务端.

ssh-agent的启动

ssh-agent这个进程启动方式比较奇特.网上给出的启动方式有以下两种:
1.eval ssh-agent
2.ssh-agent $SHELL

eval方式启动

我们先用第一种方式启动:

  1. [root@ssh_client ~]# eval `ssh-agent`
  2. Agent pid 378
  3. [root@ssh_client ~]# ssh root@172.17.0.2
  4. Enter passphrase for key '/root/.ssh/id_rsa':
  5. Last login: Sat Apr 14 13:40:31 2018 from 172.17.0.3
  6. [root@ssh_server ~]# logout
  7. Connection to 172.17.0.2 closed.
  8. [root@ssh_client ~]#
  9. [root@ssh_client ~]# ssh root@172.17.0.2
  10. Enter passphrase for key '/root/.ssh/id_rsa':
  11. Last login: Sat Apr 14 13:41:37 2018 from 172.17.0.3
  12. [root@ssh_server ~]# logout
  13. Connection to 172.17.0.2 closed.
  14. [root@ssh_client ~]# ssh-add
  15. Enter passphrase for /root/.ssh/id_rsa:
  16. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  17. [root@ssh_client ~]# ssh root@172.17.0.2
  18. Last login: Sat Apr 14 13:41:44 2018 from 172.17.0.3
  19. [root@ssh_server ~]# logout
  20. Connection to 172.17.0.2 closed.
  21. [root@ssh_client ~]# ssh root@172.17.0.2
  22. Last login: Sat Apr 14 13:42:18 2018 from 172.17.0.3
  23. [root@ssh_server ~]#

在执行完eval ssh-agent之后,尝试登录ssh服务端,还是会提示需要输入passphrase,返回客户端后,执行ssh-add,将密钥添加到agent里,这时,再次尝试登录ssh服务端不会再被要求输入passphrase, ssh-agent的功能生效.
查看下ssh-agent进程,以及环境变量

  1. [root@ssh_client ~]# ps -ef|grep ssh-agent
  2. root 378 0 0 13:41 ? 00:00:00 ssh-agent
  3. root 385 32 0 14:00 pts/1 00:00:00 grep --color=auto ssh-agent
  4. [root@ssh_client ~]# env
  5. SSH_AGENT_PID=378
  6. HOSTNAME=ssh_client
  7. TERM=xterm
  8. OLDPWD=/etc/ssh
  9. SSH_AUTH_SOCK=/tmp/ssh-ie7S93Oq08FU/agent.377
  10. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  11. PWD=/root
  12. SHLVL=1
  13. HOME=/root
  14. _=/usr/bin/env
  15. [root@ssh_client ~]# ls -tlr
  16. total 4
  17. -rw------- 1 root root 3270 Mar 2 01:07 anaconda-ks.cfg
  18. [root@ssh_client ~]# exit

退出当前会话,重新登录

  1. [root@ssh_client /]# ps -ef|grep ssh-agent
  2. root 378 0 0 13:41 ? 00:00:00 ssh-agent
  3. root 403 388 0 14:01 pts/1 00:00:00 grep --color=auto ssh-agent
  4. [root@ssh_client /]# env|grep SSH
  5. [root@ssh_client /]# ssh root@172.17.0.2
  6. Enter passphrase for key '/root/.ssh/id_rsa':

ssh-agent进程依然在,但是SSH_AGENT_PID和SSH_AUTH_SOCK环境变量不在了.此时尝试登录ssh服务端,发现需要重新输入passphrase.

  1. [root@ssh_client /]# export SSH_AGENT_PID=378
  2. [root@ssh_client /]# ssh root@172.17.0.2
  3. Enter passphrase for key '/root/.ssh/id_rsa':

重新导入SSH_AGENT_PID环境变量,再次尝试登录,还是需要passphrase.

  1. [root@ssh_client /]# export SSH_AUTH_SOCK=/tmp/ssh-ie7S93Oq08FU/agent.377
  2. [root@ssh_client /]# ssh root@172.17.0.2
  3. Last failed login: Sat Apr 14 14:02:30 UTC 2018 from 172.17.0.3 on ssh:notty
  4. There was 1 failed login attempt since the last successful login.
  5. Last login: Sat Apr 14 13:42:20 2018 from 172.17.0.3
  6. [root@ssh_server ~]# logout
  7. Connection to 172.17.0.2 closed.
  8. [root@ssh_client /]#

导入SSH_AUTH_SOCK之后,可以正常实现免输入passphrase登录ssh服务端.

手工导入环境变量方式启动

我们退出当前会话,重新登录并停止ssh-agent进程

  1. [root@ssh_client ssh-ie7S93Oq08FU]# ps -ef|grep ssh-agent
  2. root 378 0 0 Apr14 ? 00:00:00 ssh-agent
  3. root 494 476 0 01:34 pts/1 00:00:00 grep --color=auto ssh-agent
  4. [root@ssh_client ssh-ie7S93Oq08FU]# kill 378
  5. [root@ssh_client ssh-ie7S93Oq08FU]# ps -ef|grep ssh-agent
  6. root 496 476 0 01:35 pts/1 00:00:00 grep --color=auto ssh-agent
  7. [root@ssh_client ssh-ie7S93Oq08FU]# ls -ltr
  8. ls: cannot open directory .: Stale file handle

停止完进程后,这个临时SOCK文件及其目录也自动消失.
我们以正常运行软件的方式启动这个ssh-agent

  1. [root@ssh_client ~]# ssh-agent
  2. SSH_AUTH_SOCK=/tmp/ssh-3KNEl7ztz4Xh/agent.501; export SSH_AUTH_SOCK;
  3. SSH_AGENT_PID=502; export SSH_AGENT_PID;
  4. echo Agent pid 502;
  5. [root@ssh_client ~]#

执行完成之后,界面上返回三行数据,如果我们用eval方式启动,这三行数据会当成脚本被运行,相当于自动导入两个变量,并在完成后打印出Agent的pid,正是我们前面一个案例看到的效果:

  1. [root@ssh_client ~]# eval `ssh-agent`
  2. Agent pid 378
  3. [root@ssh_client ~]#

我们继续在当前案例下尝试登录ssh服务端:

  1. [root@ssh_client ~]# ssh root@172.17.0.2
  2. Enter passphrase for key '/root/.ssh/id_rsa':
  3. Last login: Sun Apr 15 01:32:24 2018 from 172.17.0.3
  4. [root@ssh_server ~]# logout

还是需要输入passphrase才能登录,执行ssh-add -l 查看当前已经加载的密钥:

  1. [root@ssh_client ~]# ssh-add -l
  2. Could not open a connection to your authentication agent.
  3. [root@ssh_client ~]#

提示没有和agent连接.
手工导入两个环境变量

  1. [root@ssh_client ~]# SSH_AUTH_SOCK=/tmp/ssh-3KNEl7ztz4Xh/agent.501; export SSH_AUTH_SOCK;
  2. [root@ssh_client ~]# SSH_AGENT_PID=502; export SSH_AGENT_PID;
  3. [root@ssh_client ~]# ssh-add -l
  4. The agent has no identities.
  5. [root@ssh_client ~]# ssh root@172.17.0.2
  6. Enter passphrase for key '/root/.ssh/id_rsa':

这时已经可以执行ssh-add -l,但是还是没有密钥,ssh还是需要输入passphrase.

  1. [root@ssh_client ~]# ssh-add
  2. Enter passphrase for /root/.ssh/id_rsa:
  3. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  4. [root@ssh_client ~]# ssh-add -l
  5. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  6. [root@ssh_client ~]# ssh root@172.17.0.2
  7. Last login: Sun Apr 15 02:24:09 2018 from 172.17.0.3
  8. [root@ssh_server ~]# logout

通过ssh-add加入密钥后,可以通过-l参数看到这个密钥,再次ssh登录服务端就不需要输入passphrase.

以新SHELL方式启动

本章节开始时,我们还提到,可以通过ssh-agent $SHELL来启动ssh-agent.
我们先退出会话,停ssh-agent进程

  1. [root@ssh_client /]# ps -ef|grep ssh-agent
  2. root 546 527 0 12:45 pts/1 00:00:00 grep --color=auto ssh-agent
  3. [root@ssh_client /]# env|grep SSH
  4. [root@ssh_client /]#

执行 ssh-agent

  1. [root@ssh_client /]# ps -ef
  2. UID PID PPID C STIME TTY TIME CMD
  3. root 1 0 0 Apr07 pts/0 00:00:00 bash
  4. root 527 0 0 Apr15 pts/1 00:00:00 bash
  5. root 550 527 0 12:46 pts/1 00:00:00 ps -ef
  6. [root@ssh_client /]# echo $SHELL
  7. /bin/bash
  8. [root@ssh_client /]# ssh-agent $SHELL
  9. [root@ssh_client /]# ps -ef
  10. UID PID PPID C STIME TTY TIME CMD
  11. root 1 0 0 Apr07 pts/0 00:00:00 bash
  12. root 527 0 0 Apr15 pts/1 00:00:00 bash
  13. root 551 527 0 12:46 pts/1 00:00:00 /bin/bash
  14. root 552 551 0 12:46 ? 00:00:00 ssh-agent /bin/bash
  15. root 561 551 0 12:46 pts/1 00:00:00 ps -ef
  16. [root@ssh_client /]# env|grep SSH
  17. SSH_AGENT_PID=552
  18. SSH_AUTH_SOCK=/tmp/ssh-WHdCTaxyK6d2/agent.551
  19. [root@ssh_client /]#

执行之前会话在pts/1上,当前的shell是进程号为527的bash.执行后,pts/1的shell已经变成/bin/bash,并且agent相关的环境变量也自动灌入,效果和eval差不多(eval没有新启动一个shell).这种启动方式是通过在执行ssh-agent后面加一个shell进程,新启动一个shell,在新shell里自动加载环境变量来实现的.
验证agent功能:

  1. [root@ssh_client /]# ssh-add -l
  2. The agent has no identities.
  3. [root@ssh_client /]# ssh-add
  4. Enter passphrase for /root/.ssh/id_rsa:
  5. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  6. [root@ssh_client /]#
  7. [root@ssh_client /]# ssh root@172.17.0.2
  8. Last login: Sun Apr 15 02:58:40 2018 from 172.17.0.3
  9. [root@ssh_server ~]# logout
  10. Connection to 172.17.0.2 closed.
  11. [root@ssh_client /]#
  12. [root@ssh_client /]#
  13. [root@ssh_client /]# exit
  14. [root@ssh_client /]#

注意最后那个exit,从ssh_client的shell退出之后,仍旧回到ssh_client里,说明pts/1有两层shell.
当我们退出里层shell时,该shell里的进程(包含ssh-agent进程)及环境变量也同步退出.

  1. [root@ssh_client /]# ps -ef
  2. UID PID PPID C STIME TTY TIME CMD
  3. root 1 0 0 Apr07 pts/0 00:00:00 bash
  4. root 527 0 0 Apr15 pts/1 00:00:00 bash
  5. root 568 527 0 13:46 pts/1 00:00:00 ps -ef
  6. [root@ssh_client /]# env|grep SSH
  7. [root@ssh_client /]#

ssh-agent的停止

前面案例中,我们已经实现了两种停止ssh-agent的方式,就是:
如果是以eval方式在当前shell里启动的ssh-agent,通过ps找到这个ssh-agent的pid,停止这个进程,同时退出会话(或者unset SSH_AUTH_SOCK和SSH_AGENT_PID这两个环境变量);
如果是通过新起一个shell实现的,直接退出新启动的shell.
ssh-agent本身也提供了一个参数ssh-agent -k,用于停进程:

  1. [root@ssh_client /]# ps -ef
  2. UID PID PPID C STIME TTY TIME CMD
  3. root 1 0 0 Apr07 pts/0 00:00:00 bash
  4. root 643 0 1 12:52 pts/1 00:00:00 bash
  5. root 657 643 0 12:52 pts/1 00:00:00 ps -ef
  6. [root@ssh_client /]# eval `ssh-agent`
  7. Agent pid 659
  8. [root@ssh_client /]# ps -ef|grep ssh-agent
  9. root 659 0 0 12:52 ? 00:00:00 ssh-agent
  10. root 661 643 0 12:53 pts/1 00:00:00 grep --color=auto ssh-agent
  11. [root@ssh_client /]# env|grep SSH
  12. SSH_AGENT_PID=659
  13. SSH_AUTH_SOCK=/tmp/ssh-O0JulD7hm5GJ/agent.658
  14. [root@ssh_client /]# ssh-add
  15. Enter passphrase for /root/.ssh/id_rsa:
  16. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  17. [root@ssh_client /]# ssh root@172.17.0.2
  18. Last login: Thu Apr 19 12:52:16 2018 from 172.17.0.3
  19. [root@ssh_server ~]# logout
  20. Connection to 172.17.0.2 closed.
  21. [root@ssh_client /]# eval `ssh-agent -k`
  22. Agent pid 659 killed
  23. [root@ssh_client /]# ps -ef|grep ssh-agent
  24. root 668 643 0 12:53 pts/1 00:00:00 grep --color=auto ssh-agent
  25. [root@ssh_client /]# env|grep SSH
  26. [root@ssh_client /]# ssh root@172.17.0.2
  27. Enter passphrase for key '/root/.ssh/id_rsa':

在上面这个会话中,我们先执行了 ssh-agent,同时添加了密钥,然后验证可以免输入passphrase登录ssh服务端,接着调用eval ssh-agent -k指令退出ssh-agent,最后通过登录ssh服务端验证了退出ssh-agent是成功的.

ssh-agent的随会话自动启动

用ssh-agent和ssh-agent -k搭配可以实现登录会话后自动执行ssh-agent,并在会话退出时自动结束会话.
以下是示例脚本,可以放在.bash_profile或者.bashrc里:

  1. # 退出会话时自动停agent进程
  2. trap '
  3. test -n "$SSH_AGENT_PID" && eval `ssh-agent -k` ;
  4. ' 0
  5. #没有agent在跑时自动启动agent及ssh-add
  6. if [ "$SSH_AUTH_SOCK" = "" ];then
  7. eval `ssh-agent`
  8. /usr/bin/tty > /dev/null && ssh-add
  9. fi

验证如下:

  1. [root@ssh_client /]# ps -ef
  2. UID PID PPID C STIME TTY TIME CMD
  3. root 1 0 0 Apr07 pts/0 00:00:00 bash
  4. root 714 0 0 13:02 pts/1 00:00:00 bash
  5. root 728 714 0 13:02 pts/1 00:00:00 ps -ef
  6. [root@ssh_client /]# env|grep SSH
  7. [root@ssh_client /]# su - root
  8. Last login: Thu Apr 19 13:01:42 UTC 2018 on pts/1
  9. Agent pid 747
  10. Enter passphrase for /root/.ssh/id_rsa:
  11. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  12. [root@ssh_client ~]# ssh-add -l
  13. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  14. [root@ssh_client ~]# env|grep SSH
  15. SSH_AGENT_PID=747
  16. SSH_AUTH_SOCK=/tmp/ssh-uAwrFLwR2m3s/agent.746
  17. [root@ssh_client ~]# ps -ef|grep ssh-agent
  18. root 747 0 0 13:02 ? 00:00:00 ssh-agent
  19. root 754 732 0 13:02 pts/1 00:00:00 grep --color=auto ssh-agent
  20. [root@ssh_client ~]# tail -10 .bash_profile
  21. trap '
  22. test -n "$SSH_AGENT_PID" && eval `ssh-agent -k` ;
  23. ' 0
  24. if [ "$SSH_AUTH_SOCK" = "" ];then
  25. eval `ssh-agent`
  26. /usr/bin/tty > /dev/null && ssh-add
  27. fi
  28. [root@ssh_client ~]# ssh root@172.17.0.2
  29. Last login: Thu Apr 19 12:53:25 2018 from 172.17.0.3
  30. [root@ssh_server ~]# logout
  31. Connection to 172.17.0.2 closed.
  32. [root@ssh_client ~]#
  33. [root@ssh_client ~]# logout
  34. Agent pid 747 killed
  35. [root@ssh_client /]# env|grep SSH
  36. [root@ssh_client /]# ssh root@172.17.0.2
  37. Enter passphrase for key '/root/.ssh/id_rsa':

su - root之后, .bash_profile生效,此时会让你直接输入passphrase用于加载密钥,然后就可以直接免密登录ssh服务端.退出会话时,也会自动停止ssh-agent进程.

密钥加载与删除

在上面的案例中,我们可以看到,密钥可以通过ssh-add指令进行加载.ssh-add默认加载的是位于$HOME/.ssh下的id_rsa,它也可以支持加载多密钥到ssh-agent中.
我们先创建一个新key,并将key拷贝到ssh-server2(172.17.0.4)上.

  1. [root@ssh_client ~]# mkdir keys
  2. [root@ssh_client ~]# cd keys/
  3. [root@ssh_client keys]# ssh-keygen -f /root/keys/k2 -t rsa
  4. Generating public/private rsa key pair.
  5. Enter passphrase (empty for no passphrase):
  6. Enter same passphrase again:
  7. Your identification has been saved in /root/keys/k2.
  8. Your public key has been saved in /root/keys/k2.pub.
  9. The key fingerprint is:
  10. SHA256:qvSCPe3JJjX7o4JbEaR+QCcVthHKvKGqOraLW4+Z4UQ root@ssh_client
  11. The key's randomart image is:
  12. +---[RSA 2048]----+
  13. | o.Oo |
  14. | + B o |
  15. | B o |
  16. | o + . |
  17. |. E o S |
  18. |.. . .o. |
  19. |. ++oo.o |
  20. |+=oO*++.. |
  21. |B=O.oB*o.. |
  22. +----[SHA256]-----+
  23. [root@ssh_client keys]# ls -tlr
  24. total 8
  25. -rw-r--r-- 1 root root 397 Apr 23 14:28 k2.pub
  26. -rw------- 1 root root 1766 Apr 23 14:28 k2
  27. [root@ssh_client keys]#
  28. [root@ssh_client keys]# ssh-copy-id -i k2.pub root@172.17.0.2
  29. /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "k2.pub"
  30. /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
  31. /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
  32. Enter passphrase for key '/root/.ssh/id_rsa':
  33. Number of key(s) added: 1
  34. Now try logging into the machine, with: "ssh 'root@172.17.0.2'"
  35. and check to make sure that only the key(s) you wanted were added.
  36. [root@ssh_client keys]# ssh-copy-id -i k2.pub root@172.17.0.4
  37. /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "k2.pub"
  38. The authenticity of host '172.17.0.4 (172.17.0.4)' can't be established.
  39. ECDSA key fingerprint is SHA256:Z24pWQCUSlqJF7Nyx0iA4AE/Z5z5WJWbSKA6AFspDbA.
  40. ECDSA key fingerprint is MD5:a7:a5:b2:42:ba:be:dd:f1:5f:fe:5c:89:9c:b9:eb:c3.
  41. Are you sure you want to continue connecting (yes/no)? yes
  42. /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
  43. /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
  44. root@172.17.0.4's password:
  45. Number of key(s) added: 1
  46. Now try logging into the machine, with: "ssh 'root@172.17.0.4'"
  47. and check to make sure that only the key(s) you wanted were added.
  48. [root@ssh_client keys]# ssh -i /root/keys/k2 'root@172.17.0.4'
  49. Enter passphrase for key '/root/keys/k2':
  50. Last failed login: Mon Apr 23 14:29:56 UTC 2018 from 172.17.0.3 on ssh:notty
  51. There was 1 failed login attempt since the last successful login.
  52. Last login: Sat Apr 7 08:54:56 2018 from gateway
  53. [root@ssh_server2 ~]# logout
  54. Connection to 172.17.0.4 closed.

启动ssh-agent

  1. [root@ssh_client /]# eval `ssh-agent`
  2. Agent pid 977
  3. [root@ssh_client /]# ssh-add -l
  4. The agent has no identities.
  5. [root@ssh_client /]#

默认没有加载key,执行ssh-add加载key.

  1. [root@ssh_client /]# ssh-add
  2. Enter passphrase for /root/.ssh/id_rsa:
  3. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  4. [root@ssh_client /]# ssh-add -l
  5. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  6. [root@ssh_client /]# ssh root@172.17.0.2
  7. Last login: Mon Apr 23 14:10:17 2018 from 172.17.0.3
  8. [root@ssh_server ~]# logout
  9. Connection to 172.17.0.2 closed.
  10. [root@ssh_client /]# ssh root@172.17.0.4
  11. root@172.17.0.4's password:

到172.17.0.2是免密的,到172.17.0.4还是要输入密码.
再执行一个带文件路径的ssh-add

  1. [root@ssh_client /]# ssh-add /root/keys/k2
  2. Enter passphrase for /root/keys/k2:
  3. Identity added: /root/keys/k2 (/root/keys/k2)
  4. [root@ssh_client /]# ssh-add -l
  5. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  6. 2048 SHA256:qvSCPe3JJjX7o4JbEaR+QCcVthHKvKGqOraLW4+Z4UQ /root/keys/k2 (RSA)
  7. [root@ssh_client /]# ssh root@172.17.0.4
  8. Last login: Mon Apr 23 14:31:18 2018 from 172.17.0.3
  9. [root@ssh_server2 ~]# logout
  10. Connection to 172.17.0.4 closed.
  11. [root@ssh_client /]# ssh root@172.17.0.2
  12. Last login: Mon Apr 23 14:43:01 2018 from 172.17.0.3
  13. [root@ssh_server ~]# logout
  14. Connection to 172.17.0.2 closed.

到172.17.0.4也实现了免密.
ssh-add还支持删除已经加载到agent的key,用ssh-add -d可以删除指定路径下的key:

  1. [root@ssh_client /]# ssh-add -l
  2. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  3. 2048 SHA256:qvSCPe3JJjX7o4JbEaR+QCcVthHKvKGqOraLW4+Z4UQ /root/keys/k2 (RSA)
  4. [root@ssh_client /]# ssh-add -d /root/.ssh/id_rsa
  5. Identity removed: /root/.ssh/id_rsa (root@ssh_client)
  6. [root@ssh_client /]# ssh-add -l
  7. 2048 SHA256:qvSCPe3JJjX7o4JbEaR+QCcVthHKvKGqOraLW4+Z4UQ /root/keys/k2 (RSA)
  8. [root@ssh_client /]# ssh root@172.17.0.2
  9. Enter passphrase for key '/root/.ssh/id_rsa':
  10. [root@ssh_client /]# ssh root@172.17.0.4
  11. Last login: Mon Apr 23 14:45:19 2018 from 172.17.0.3
  12. [root@ssh_server2 ~]# logout
  13. Connection to 172.17.0.4 closed.

ssh-add -D指令用于删除agent里的所有key:

  1. [root@ssh_client /]# ssh-add
  2. Enter passphrase for /root/.ssh/id_rsa:
  3. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  4. [root@ssh_client /]# ssh-add -l
  5. 2048 SHA256:qvSCPe3JJjX7o4JbEaR+QCcVthHKvKGqOraLW4+Z4UQ /root/keys/k2 (RSA)
  6. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  7. [root@ssh_client /]# ssh root@172.17.0.2
  8. Last login: Mon Apr 23 23:41:38 2018 from 172.17.0.3
  9. [root@ssh_server ~]# logout
  10. Connection to 172.17.0.2 closed.
  11. [root@ssh_client /]# ssh-add -D
  12. All identities removed.
  13. [root@ssh_client /]# ssh-add -l
  14. The agent has no identities.
  15. [root@ssh_client /]# ssh root@172.17.0.2
  16. Enter passphrase for key '/root/.ssh/id_rsa':
  17. [root@ssh_client /]# ssh root@172.17.0.4
  18. root@172.17.0.4's password:

注意到在ssh-agent里没有任何key的时候,ssh到172.17.0.2和172.17.0.4的行为是不一样的,到172.17.0.2是要求输入passphrase而到172.17.0.4是要求输入password.因为ssh默认是优先用key进行登录,默认的key在$HOME/.ssh/id_rsa,在本例中只配置到172.17.0.2上.而172.17.0.4的key不在默认位置上,因此走到了密码登录逻辑.

密钥加载时限

ssh-add在加载key的时候,可以指定key的有效期

  1. [root@ssh_client /]# ssh-add -t 30
  2. Enter passphrase for /root/.ssh/id_rsa:
  3. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  4. Lifetime set to 30 seconds
  5. [root@ssh_client /]# sleep 20
  6. [root@ssh_client /]# ssh root@172.17.0.2
  7. Last login: Mon Apr 23 14:00:48 2018 from 172.17.0.3
  8. [root@ssh_server ~]# logout
  9. Connection to 172.17.0.2 closed.
  10. [root@ssh_client /]#
  11. [root@ssh_client /]# sleep 10
  12. [root@ssh_client /]# ssh root@172.17.0.2
  13. Enter passphrase for key '/root/.ssh/id_rsa':

从上面的例子可以看出在有效期过了之后,ssh免密登录就失效.
ssh-add -t 后面还可以指定时间单位:

  1. [root@ssh_client /]# ssh-add -t 30m
  2. Enter passphrase for /root/.ssh/id_rsa:
  3. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  4. Lifetime set to 1800 seconds
  5. [root@ssh_client /]# ssh-add -t 30h
  6. Enter passphrase for /root/.ssh/id_rsa:
  7. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  8. Lifetime set to 108000 seconds
  9. [root@ssh_client /]# ssh-add -t 3d
  10. Enter passphrase for /root/.ssh/id_rsa:
  11. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  12. Lifetime set to 259200 seconds
  13. [root@ssh_client /]# ssh-add -t 3w
  14. Enter passphrase for /root/.ssh/id_rsa:
  15. Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
  16. Lifetime set to 1814400 seconds

锁定ssh-agent

ssh-add还能实现ssh-agent的锁定,暂停ssh-agent的功能,同时也不允许更新key.
查看当前加载的key,并验证两个ssh服务端都能免密登录

  1. [root@ssh_client /]# ssh-add -l
  2. 2048 SHA256:qvSCPe3JJjX7o4JbEaR+QCcVthHKvKGqOraLW4+Z4UQ /root/keys/k2 (RSA)
  3. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  4. [root@ssh_client /]# ssh root@172.17.0.4
  5. Last login: Mon Apr 23 23:42:04 2018 from 172.17.0.3
  6. [root@ssh_server2 ~]# logout
  7. Connection to 172.17.0.4 closed.
  8. [root@ssh_client /]# ssh root@172.17.0.2
  9. Last login: Mon Apr 23 23:43:51 2018 from 172.17.0.3
  10. [root@ssh_server ~]# logout
  11. Connection to 172.17.0.2 closed.

执行ssh-add锁定

  1. [root@ssh_client /]# ssh-add -x
  2. Enter lock password:
  3. Again:
  4. Agent locked.
  5. [root@ssh_client /]# ssh-add -l
  6. The agent has no identities.
  7. [root@ssh_client /]# ssh root@172.17.0.2
  8. Enter passphrase for key '/root/.ssh/id_rsa':
  9. [root@ssh_client /]# ssh root@172.17.0.4
  10. root@172.17.0.4's password:
  11. [root@ssh_client /]#
  12. [root@ssh_client /]# ssh-add
  13. Enter passphrase for /root/.ssh/id_rsa:
  14. Could not add identity "/root/.ssh/id_rsa": agent refused operation
  15. [root@ssh_client /]#

执行锁定操作,会被要求输入锁定密码,解锁时需要这个密码.锁定后,ssh-add -l查询不到key,也无法再免密登录ssh服务端,试图加载key也会失败.
解锁过程如下:

  1. [root@ssh_client /]# ssh-add -X
  2. Enter lock password:
  3. Agent unlocked.
  4. [root@ssh_client /]# ssh-add -l
  5. 2048 SHA256:qvSCPe3JJjX7o4JbEaR+QCcVthHKvKGqOraLW4+Z4UQ /root/keys/k2 (RSA)
  6. 2048 SHA256:XVtu4pjbOq39iJeG13+Ml6IFjoy/7pfv7YwSByyvV4U /root/.ssh/id_rsa (RSA)
  7. [root@ssh_client /]# ssh root@172.17.0.4
  8. Last login: Tue Apr 24 13:08:13 2018 from 172.17.0.3
  9. [root@ssh_server2 ~]# logout
  10. Connection to 172.17.0.4 closed.
  11. [root@ssh_client /]# ssh root@172.17.0.2
  12. Last login: Tue Apr 24 13:08:16 2018 from 172.17.0.3
  13. [root@ssh_server ~]# logout
  14. Connection to 172.17.0.2 closed.