zoukankan      html  css  js  c++  java
  • 了解ssh代理:ssh-agent

    ssh代理是一个程序,它可以帮助我们管理私钥,ssh-agent即为ssh代理程序。

    那么什么时候需要ssh代理帮助我们管理私钥呢?当遇到如下情况时,我们会需要ssh代理。

    1、使用不同的密钥连接到不同的主机时,需要手动指定对应的密钥,ssh代理可以帮助我们选择对应的密钥进行认证,不用手动指定密钥即可进行连接。

    2、当私钥设置了密码,我们又需要频繁的使用私钥进行认证时,ssh代理可以帮助我们免去重复的输入密码的操作。

    上述两种情况我们会一一道来,不过在描述它们之前,我们先来了解一下怎样使用ssh代理。

    启动ssh代理并添加密钥

    首先,如果想要使用ssh代理,我们则需要先启动ssh代理,也就是启动ssh-agent程序,如下两条命令都可以启动代理,但是略有不同。

    ssh-agent $SHELL
    
    eval `ssh-agent`

    如果你最小化安装了centos,那么你执行上述命令时,可能会提示找不到ssh-agent命令,此时你需要安装openssh-clients,安装后即可使用上述命令。

    当我们使用"ssh-agent $SHELL"命令时,会在当前shell中启动一个默认shell,作为当前shell的子shell,ssh-agent程序会在子shell中运行,当执行"ssh-agent $SHELL"命令后,我们也会自动进入到新创建的子shell中,centos中,默认shell通常为bash,所以,在centos中上述命令通常可以直接写为ssh-agent bash,当然,如果你的默认shell已经指定为其他shell,比如csh,那么你也可以直接使用ssh-agent csh,效果都是相同的,我们来实验一下。

    当前使用的centos系统的默认shell为bash,在未启动ssh-agent程序时,我们在当前bash中执行pstree命令,查看sshd的进程树,如下

    然后,执行"ssh-agent $SHELL"命令(注意:SHELL为大写),启动ssh代理,执行此命令后,再次使用pstree命令,查看sshd的进程树

    在原来的bash中新生成了一个子bash,ssh-agnet运行在子bash中,我们的命令也同样在子bash中执行。

    此时,在当前会话中,我们已经可以使用ssh-agent了,ssh-agent会随着当前ssh会话的消失而消失,这也是一种安全机制,比如,退出当前子shell,再次查看进程树。

    [root@server01 ~]# exit
    exit

    可以看到ssh-agent已经不再存在了,如果你的服务器中开启了图形化环境,使用"ps -ef | grep ssh-agent"命令查找ssh-agent进程,仍然能够看到一个ssh-agent进程,这个ssh-agent进程是跟随图形化界面开机启动的,但是通常,服务器中很少会开启图形化界面,所以我们不用在意它。

    虽然我们已经知道了怎样启动ssh-agent,但是,如果想让ssh代理帮助我们管理密钥,还需要将密钥添加到ssh代理中

    刚才执行了ssh-agent $SHELL命令,现在试试 eval `ssh-agent` 命令。

    eval `ssh-agent`命令并不会启动一个子shell,而是会直接启动一个ssh-agent进程,示例如下

    [root@server01 ~]# eval `ssh-agent`
    Agent pid 37776
    [root@server01 ~]# pstree

    可以看到,ssh-agent进程已经启动了,此刻,如果我们推出当前bash,此ssh-agnet进程并不会自动关闭,所以,我们应该在退出当前bash之前,手动的关闭这个进程,在当前bash中,使用ssh-agent -k命令可以关闭对应的ssh-agent进程,但是,如果在退出了当前bash以后再使用'ssh-agent -k'命令,是无法关闭对应的ssh-agent进程的,除非使用kill命令,当然,其实在使用 ssh-agent $SHELL 命令时,也可以使用'ssh-agent -k'命令关闭ssh代理。

    好了,我们已经了解了怎样启动ssh代理,以及怎样关闭ssh代理,但是,我们还没有真正的使用过代理,如果想要真正的使用ssh代理帮助我们管理密钥,还需要将密钥添加到代理中,添加密钥需要使用到ssh-add命令

    ssh-add命令的使用方法非常简单,示例如下

    ssh-add  ~/.ssh/id_rsa_custom

    上述命令表示将私钥id_rsa_custom加入到ssh代理中,如果你没有正确的启动ssh-agent,那么你在执行ssh-add命令时,可能会出现如下错误提示。

    Could not open a connection to your authentication agent.

    完成上述步骤后,ssh代理即可帮助我们管理id_rsa_custom密钥了,那么有哪些具体的使用场景呢,我们继续聊。

    ssh代理帮助我们选择对应的私钥进行认证

    前一篇文章中,我们总结了基于密钥进行认证的方法,比如,我们在生成密钥对时,可以手动指定密钥的名称,而不是使用默认的密钥名称,示例如下:

    [root@server01 ~]# ssh-keygen 
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/id_rsa_test1
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /root/.ssh/id_rsa_test1.
    Your public key has been saved in /root/.ssh/id_rsa_test1.pub.
    The key fingerprint is:
    SHA256:X+3iV0UbGX2tPfXRPnQfINoB3orEkXz42mgDOnNQ/vg root@server01
    The key's randomart image is:
    +---[RSA 2048]----+
    |      ..o..o ...*|
    |     ..+o.+ o  *O|
    |    o  ooo o  .=@|
    |   . o. ...  ..+*|
    |    o +.S.  . . +|
    |   + o * o . .  .|
    |    + o . . . .. |
    |       E   . ..  |
    |            ..   |
    +----[SHA256]-----+
    [root@server01 ~]# ssh-copy-id -i /root/.ssh/id_rsa_test1.pub root@192.168.0.221
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa_test1.pub"
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /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
    root@192.168.0.221's password: 
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'root@192.168.0.221'"
    and check to make sure that only the key(s) you wanted were added.
    
    [root@server01 ~]# ssh root@192.168.0.221
    root@192.168.0.221's password: 

    如上例所示,我们将公钥id_rsa_test1.pub发送给了192.168.0.221的root用户,然后在A机器(192.168.0.220)上连接到C机器(192.168.0.221)时,仍然提示我们输入root@192.168.0.221的密码,这是因为ssh基于密钥进行认证时,默认会使用~/.ssh/id_rsa进行认证,当你使用非默认名称的私钥进行认证时,需要手动指明对应的私钥,如果不指明对应的私钥,ssh仍然会默认使用~/.ssh/id_rsa进行认证,上例就是这种情况,由于我们没有使用~/.ssh/id_rsa进行认证,同时没有指明对应的私钥,ssh会使用id_rsa与id_rsa_test1.pub进行匹配,它们本来就不是一对密钥,自然无法认证成功,所以ssh仍然提示我们输入密码,我们可以使用 -i 选项指定对应的私钥文件进行认证,示例如下

    [root@server01 ~]# ssh -i /root/.ssh/id_rsa_test1 root@192.168.0.221
    Last login: Wed Dec 30 16:11:27 2020 from server01
    [root@server02 ~]# 

    如上例所示,指明对应的私钥后,即可正常的使用密钥进行认证,从而免去输入用户的密码。

    如果我们手中有很多密钥对,它们对应的公钥被不同的服务器所持有,那么,我们连接不同的服务器时,就需要手动指定对应的不同的私钥,而ssh代理可以帮助我们管理这些私钥,从而避免手动的指定私钥。

    示例如下

    [root@server01 ~]# ssh-agent bash
    [root@server01 ~]# ssh-add /root/.ssh/id_rsa_test1
    Identity added: /root/.ssh/id_rsa_test1 (/root/.ssh/id_rsa_test1)
    [root@server01 ~]# ssh root@192.168.0.221
    Last login: Wed Dec 30 16:20:05 2020 from server01
    [root@server02 ~]# 

    如上例所示,我们启动了ssh-agent进程,然后将私钥id_rsa_test1加入到了ssh代理中,再次使用非默认名称的私钥进行认证时,并不用指明密钥,ssh-agent会帮助我们选择对应的私钥,进行正确的认证,当本机有多个密钥对,并且它们的公钥分布于很多不同的机器时,会非常有用。

    ssh代理能够免去重复输入私钥密码的操作

    当我们为私钥设置了密码,ssh基于密钥进行认证时,会提示输入私钥的密码,输入正确的私钥密码,才能够使用对应私钥进行认证,示例如下

    生成密钥对,同时指定私钥的密码

    [root@server02 ~]# ssh-keygen -f ~/.ssh/id_rsa_test2 -P'123456'  
    Generating public/private rsa key pair.
    Your identification has been saved in /root/.ssh/id_rsa_test2.
    Your public key has been saved in /root/.ssh/id_rsa_test2.pub.
    The key fingerprint is:
    SHA256:TodsdT4tyAWcS4ah74pbVbIy6ayb61tIjrLq7ck9br0 root@server02
    The key's randomart image is:
    +---[RSA 2048]----+
    |        .+..     |
    |       .. =.     |
    |      . .oo.o    |
    |       + B.= .   |
    |    . + S + + .  |
    |   + + O .   o   |
    |. . o * o        |
    | oo oO o         |
    |=..*%BoE.        |
    +----[SHA256]-----+
    [root@server02 ~]# 

    [root@server01 .ssh]# ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (/root/.ssh/id_rsa): /root/.ssh/id_rsa_test2
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /root/.ssh/id_rsa_test2.
    Your public key has been saved in /root/.ssh/id_rsa_test2.pub.
    The key fingerprint is:
    SHA256:DSPuClMA0lnPS49eS9FQpZHBveV4AjjWDfQXfGjlyto root@server01
    The key's randomart image is:
    +---[RSA 2048]----+
    |o. o. .**B...o.|
    |..o o +o=+o =o.|
    | . =.+.o..*...|
    | . o = = +oo. |
    | . + S . oo |
    | . o o . o |
    | o o . . E |
    | o . |
    | . |
    +----[SHA256]-----+

    [root@server02 ~]# ssh-copy-id -i ~/.ssh/id_rsa_test2.pub root@192.168.0.221
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa_test2.pub"
    The authenticity of host '192.168.0.221 (192.168.0.221)' can't be established.
    ECDSA key fingerprint is SHA256:tcswoU/iM4uZXPrY28mUh7YlQvl/DHE1SeLwIX0mhs0.
    ECDSA key fingerprint is MD5:ff:8b:91:0c:a0:38:44:5c:67:31:f1:64:91:8c:79:18.
    Are you sure you want to continue connecting (yes/no)? yes
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /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
    root@192.168.0.221's password: 
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'root@192.168.0.221'"
    and check to make sure that only the key(s) you wanted were added.
    
    [root@server02 ~]# 

    指定对应私钥连接远程用户,提示输入对应私钥的密码,正确的输入私钥的密码,即可连接到远程用户

    [root@server01 .ssh]# ssh -i /root/.ssh/id_rsa_test2 root@192.168.0.221
    Last login: Wed Dec 30 16:27:53 2020 from server01
    [root@server02 ~]# ssh-agent bash
    [root@server02 ~]# ssh-add /root/.ssh/id_rsa_test2
    Enter passphrase for /root/.ssh/id_rsa_test2: 
    Identity added: /root/.ssh/id_rsa_test2 (/root/.ssh/id_rsa_test2)

    ssh代理能够免去重复输入私钥密码的操作

    当我们为私钥设置了密码,ssh基于密钥进行认证时,会提示输入私钥的密码,输入正确的私钥密码,才能够使用对应私钥进行认证,示例如下

    生成密钥对,同时指定私钥的密码

    ssh-keygen -f ~/.ssh/id_rsa_test2 -P'123456'

      

    将公钥添加到远程用户的公钥认证文件中,提示输入远程用户的密码。

    ssh-copy-id -i ~/.ssh/id_rsa_test2.pub root@192.168.0.221

    root@192.168.0.221's password:

      

    指定对应私钥连接远程用户,提示输入对应私钥的密码,正确的输入私钥的密码,即可连接到远程用户

    ssh -i ~/.ssh/id_rsa_test2 root@192.168.0.221

    Enter passphrase for key '/root/.ssh/id_rsa_test2':

      

    但是,如果为私钥设置了密码,每次使用私钥进行认证连接是,都会要求输入私钥密码,如果你在当前ssh会话中需要反复的连接到远程用户,那么反复的输入复杂的私钥密码,的确会比较麻烦,ssh-agent可以帮助我们,在一个ssh会话中,只要输入一次私钥密码,在同一ssh会话中之后再次使用到相同的私钥时,即可不用再次输入对应密码,示例如下。

    [root@server01 .ssh]# ssh-agent bash
    [root@server01 .ssh]# ssh-add /root/.ssh/id_rsa_test2
    Enter passphrase for /root/.ssh/id_rsa_test2: 
    Identity added: /root/.ssh/id_rsa_test2 (/root/.ssh/id_rsa_test2)
    [root@server01 .ssh]# ssh -i /root/.ssh/id_rsa_test2 root@192.168.0.221
    Last login: Wed Dec 30 16:42:57 2020 from server02
    [root@server02 ~]# 

    如上图所示

    第1步:启动ssh代理

    第2步:将对应私钥添加到ssh代理中,在添加私钥时,会提示输入私钥的密码,此时,正确的输入私钥密码即可将私钥添加到ssh代理中。

    第3步:连接到远程用户,并使用对应私钥进行认证,已经不用输入私钥密码,即可连接到远程用户,从远程用户的会话中退出,回到当前ssh会话中。

    第4步:在当前会话中,再次连接到远程用户,同样没有提示输入密码。

    从上述示例可以看出,在同一个ssh会话中,ssh-agent可以帮助我们免去重复输入私钥密码的操作。

    管理ssh代理中的密钥

    如果我们想要查看ssh代理中已经添加了哪些私钥,该怎样查看呢?使用'ssh-add -l'即可查看,示例如下

    [root@server01 .ssh]# ssh-add -L
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCRifoMpVSR1txm8ek63wLeF6B6tm42mKRVTPcStinxyLeYpmi/IcJDOemopA6fHNeyupNoLluwCpeSukv8IBAqt1oeE+QI+rmecPBl/d9n1XoeI8tIrm1cMp8pz7CEX5k7ijquSnvMU8YsLM5J7a4S2GX+mXHAw/NUU6MhkhDjEmDVV7+qpvOVpK6rWALl05crMavyDujDi30Fyy7tsn8RNap2ja/1TWewegBD/bpW/9RwGcWKrekpz+UqGB/D33/gx7TTKeXaeIaOgEqqsuJB0ztZrsTjtQDvO28L+KvZOpIaxTMuyKKgBtU1SEIu6m/gKH0z3UUCsbMVoaTi4mUV /root/.ssh/id_rsa_test2
    [root@server01 .ssh]# ssh-add -l
    2048 SHA256:DSPuClMA0lnPS49eS9FQpZHBveV4AjjWDfQXfGjlyto /root/.ssh/id_rsa_test2 (RSA)

    如果我们想要从代理中移除某个已经添加的私钥,可以使用'ssh-add -d'命令指定要移除的私钥,示例如下

    [root@server02 .ssh]# ssh-add -d /root/.ssh/id_rsa_test2

    我们也可以一次性清空代理中的所有私钥,使用'ssh-add -D'命令即可。

    如果我们想要临时锁定ssh代理,则可以对ssh代理添加密码,并进行锁定,锁定后的ssh代理无法继续帮助我们管理私钥,除非解锁以后,才能正常的帮助我们管理私钥,示例如下,在正常情况下,ssh代理可以帮助我们管理私钥,我们可以使用'ssh-add -x'命令对代理加锁,加锁时会提示输入密码,这个密码在解锁时需要用到,加锁后,再次连接远程用户时,ssh代理已经失效,除非我们对代理进行解锁,使用'ssh-add -X'命令(大写X)对代理解锁,解锁时需要输入加锁时设定的密码,解锁后,ssh代理恢复正常。

    总结

    启动ssh-agent

    如下两种方式均可启动ssh-gent

    方式一:创建子shell,在子shell中运行ssh-agent进程,退出子shell自动结束代理。

    方式二:单独启动一个代理进程,退出当前shell时最好使用ssh-agent -k关闭对应代理

      

    关闭ssh-agent

      

    将私钥添加到ssh代理

      

    查看代理中的私钥

      

    查看代理中的私钥对应的公钥

      

    移除指定的私钥

      

    移除代理中的所有私钥

      

    锁定ssh代理

    锁定时需要指定锁定密码,锁定后的ssh代理暂时不能帮助我们管理私钥

      

    解锁ssh代理

    解锁时需要输入创建锁时设定的密码,解锁后ssh代理可正常工作

  • 相关阅读:
    1312. Minimum Insertion Steps to Make a String Palindrome
    【堆】23. Merge k Sorted Lists
    LeetCode 406 根据身高重建队列
    LeetCode 922 按奇偶排序数组II
    LeetCode 31 下一个排列
    LeetCode 941 有效的山脉数组
    LeetCode 面试题4 二维数组中的查找
    LeetCode 463 岛屿的周长
    LeetCode 129 求根到叶子节点数字之和
    LeetCode 1207 独一无二的出现次数
  • 原文地址:https://www.cnblogs.com/liujunjun/p/14212295.html
Copyright © 2011-2022 走看看