使用ssh-agent

ssh-agent是一种控制用来保存公钥身份验证所使用的私钥的程序。 ssh-agent在X会话或登录会话之初启动,所有其他窗口或程序则以客户端程序的身份启动并加入到ssh-agent程序中。通过使用环境变量,可定位代理并在登录到其他使用ssh机器上时使用代理自动进行身份验证。不同于ssh,ssh-agent是个长时间持续运行的守护进程(daemon),设计它的唯一目的就是对解密的专用密钥进行高速缓存。

ssh包含的内建支持允许它同ssh-agent通信,允许ssh不必每次新连接时都提示您要密码才能获取解密的专用密钥。对于ssh-agent,您只要使用ssh-add把专用密钥添加到ssh-agent的高速缓存中。这是个一次性过程;用过ssh-add之后,ssh将从ssh-agent获取您的专用密钥,而不会提示要密码短语来烦您了。

其实ssh-agent就是一个密钥管理器,运行ssh-agent以后,使用ssh-add将私钥交给ssh-agent保管,其他程序需要身份验证的时候可以将验证申请交给ssh-agent来完成整个认证过程。通过使用ssh-agent就可以很方便的在不的主机间进行漫游了,假如我们手头有三台server:host1、host2、host3且每台server上到保存了本机(supersun.biz)的公钥,因此我可以通过公钥认证登录到每台主机:

[[email protected] ~]#ssh host1
Last login: Thu Oct 18 13:56:08 2007 from supersun
[root@host1 root]# 

[[email protected] ~]#ssh host2
Last login: Fri Oct 12 11:14:44 2007 from supersun
[root@host2 root]# 

[[email protected] ~]#ssh host3
Last login: Sat Sep 29 10:21:32 2007 from supersun
[root@host3 root]# 

但是这三台server之间并没有并没有保存彼此的公钥,而且我也不可能将自己的私钥存放到server上(不安全),因此彼此之间没有公钥进 行认证(可以密码认证,但是这样慢,经常输密码,烦且密码太多容易忘)。但是如果我们启用ssh-agent,问题就可以迎刃而解了。

启用ssh-agent:

[root@supersun.biz ~]#eval `ssh-agent `
Agent pid 3526

添加私钥:

[root@supersun.biz ~]#ssh-add
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)

编缉/etc/ssh/ssh_config文件:ForwardAgent yes

让ssh-agent能转发,这样就可以这样登陆了:supersun.biz—->host1—->host2,到此请注意,如果host1上没有设定转发的话就登不了host3了,设定了转发后可以进一步跳到rs3上了。

[root@supersun.biz ~]#ssh host1
Last login: Thu Oct 18 16:21:29 2007 from supersun
[root@host1 root]# vi /etc/ssh/ssh_config 
[root@host1 root]# ssh host2
Last login: Thu Oct 18 16:20:28 2007 from supersun
[root@host2 root]# ssh host3
Last login: Thu Oct 18 16:10:39 2007 from supersun
[root@host3 root]# 

到这里基本上已经大功告成了,还有一个小问题那就是总不能每次都手动运行ssh-agent吧!最省时的方法就是将它写到profile中去:
我在在/etc/profile.d下建一个ssh-agent.sh文件:

[[email protected] ~]#cat /etc/profile.d/ssh-agent.sh 
#!/bin/sh
if [ -f ~/.agent.env ]; then
        . ~/.agent.env >/dev/null
        if ! kill -0 $SSH_AGENT_PID >/dev/null 2>&1; then
                echo "Stale agent file found. Spawning new agent..."
                eval `ssh-agent |tee ~/.agent.env`
                ssh-add
        fi
else
        echo "Starting ssh-agent..."
        eval `ssh-agent |tee ~/.agent.env`
        ssh-add
fi

这样就不会生成太多的ssh-agent程序了,而且支持GUI环境。当我打开一个终端的话:

Stale agent file found. Spawning new agent...
Agent pid 2543
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
[root@supersun.biz ~]#

添加了新的密钥。

让我们看一下整个ssh-agent密钥高速缓存系统的工作过程。ssh-agent启动时,在脱离shell(外壳程序)并继续在后台运行之前它会输出一些重要的环境变量。以下是ssh-agent开始时生成的输出的一些示例:

ssh-agentSSH_AUTH_SOCK=/tmp/ssh-XX4LkMJS/agent.26916;
exportSSH_AUTH_SOCK;SSH_AGENT_PID=26917;
exportSSH_AGENT_PID;
echoAgentpid26917

正如您所看到的,事实上ssh-agent的输出是一系列bash命令;如果这些命令被执行,则将设置两个环境变量:SSH_AUTH_SOCK和SSH_AGENT_PID。内含的export命令使这些环境变量对之后运行的任何附加命令都可用。唔,如果shell真对这些行进行计算,这一切才会发生,但是此时它们只是被打印到标准输出(stdout)而已。要使之确定,我们可以象下面这样调用ssh-agent:

eval`ssh-agent`

这个命令先让bash运行ssh-agent后对ssh-agent的输出进行计算。shell以这种调用方式(使用反引号,而不是普通的单引号)设置并导出SSH_AGENT_PID及SSH_AUTH_SOCK变量,使这些变量对于您在登录会话期间启动的所有新进程都可用。

启动ssh-agent的最佳方式就是把上面这行添加到您的~/.bash_profile中;这样,在您的登录shell中启动的所有程序都将看到环境变量,而且能够定位ssh-agent,并在需要的时候向其查询密钥。尤其重要的环境变量是SSH_AUTH_SOCK;SSH_AUTH_SOCK包含有ssh和scp可以用来同ssh-agent建立对话的UNIX域套接字的路径。

使用ssh-add
但是ssh-agent启动时高速缓存当然是空的,里面不会有解密的专用密钥。在我们真能使用ssh-agent之前,首先还需要使用ssh-add命令把我们的专用密钥添加到ssh-agent的高速缓存中。下面的示例中,我使用ssh-add把我的~/.ssh/identity专用RSA密钥添加到ssh-agent的高速缓存中:

ssh-add (私钥地址)

正如您所看到的,ssh-add要我的密码短语来对专用密钥进行解密并存储在ssh-agent的高速缓存中以备使用。一旦您已经用ssh-add把专用密钥(或多个密钥)添加到ssh-agent的高速缓存中,并在当前的shell中(如果您在~/.bash_profile中启动ssh-agent,情况应当是这样)定义SSH_AUTH_SOCK,那么您可以使用scp和ssh同远程系统建立连接而不必提供密码短语。

你可能感兴趣的:(ssh,实用技术)