SSH Agent Forwarding原理讲了ssh认证以及agent forwarding的基本原理, 但没有讲具体该怎么做。下面就讲讲最佳实践 (Best Practice). Using ssh-agent with ssh一文讲得很清楚,这里做一下翻译和扩展。


公钥认证配置

  1. 在本机生成公私钥对
ssh-keygen -f $HOME/.ssh/id_rsa -C "you@example.com"

会提示你输入passphrase, 请务必要输入passphrase, 不然有很大安全风险。另外请把命令中的email换成你自己的真实email.

$HOME/.ssh下生成id_rsaid_rsa.pub两个文件。前者是你的私钥(身份标识),请不要泄露给任何人,后者是公钥,可随意分发,下面会讲到如何使用。原理部分已经提到,其实id_rsa.pub中的内容可通过ssh-keygen -y $HOME/.ssh/id_rsa提取出来。单独生成一个文件只是为了方便之后使用。

id_rsa可以作为你的身份标识,当你更换机器或重装系统的时候,请记得备份并随后恢复这两个文件,而不要再重新生成。如果你有多台机器,也建议使用同一份id_rsa.

$HOME/.ssh/authorized_keys

  1. 以允许公钥认证

homepc

  1. 通过公钥以用户

yourname

  1. 的身份登陆远程机器

box

  1. ,则需要将你的公钥添加到

yourname@box

  1. (表示box机器的用户

yourname

  1. )的

$HOME/.ssh/authorized_keys

  1. 中。如果你能够以密码认证的方式登陆

yourname@box

  1. , 则可在

homepc

  1. 执行如下命令
cat ~/.ssh/id_dsa.pub | ssh yourname@box 'cat - >> ~/.ssh/authorized_keys'

或使用更简单的命令

ssh-copy-id yourname@box

如果你没有权限访问此机器,则可以请系统管理员代你进行操作。

  1. 验证公钥认证是否工作

yourname@box

  1. ,这时会提示你输入passphrase, 如果输入之后能成功登陆,那证明配置成功了。
$ ssh yourname@box
Enter passphrase for RSA key 'you@example.com':

如果上述步骤不成功,请检查配置是否正确

$ ls -lah $HOME/.ssh
drwx------  3 ping ping 4.0K 2012-08-29 18:08 .
-rw-------  1 ping ping  314 2010-08-27 00:56 id_rsa

主要确认.ssh/id_rsa存在且.ssh和.ssh/id_rsa的owner和权限正确,即owner必须为当前用户且只能当前用户可读写,这样以防止私钥被其他用户访问。

如果不正确,可通过如下命令纠正

sudo chown -R $USER:$USER .ssh # 仅当owner不正确时执行此步
chmod 700 .ssh
chmod 600 .ssh/id_rsa

配置成功后,想要无passphrase登陆?下面就讲如何配置ssh agent以及agent forwarding.

agent forwarding配置

$SSH_AUTH_SOCK环境变量,只要这个环境变量存在, ssh client就会通过此变量指向的域套接字 (domain socket)和agent通信从而实现私钥通过agent管理。所以配置时注意两点就可以了

  1. ssh-agent已经启动,且私钥已纳入了管理
  2. $SSH_AUTH_SOCK环境变量被正确设置

做法有两种,一种是将需要程序作为ssh-agent的子进程启动,比如



ssh-agent gnome-session



 

$SSH_AUTH_SOCK,所有在shell中执行的命令自动继承此环境变量。$HOME/.bashrc


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 -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
  start_agent;
}
else
  start_agent;
fi


source $HOME/.ssh/environment给当前shell设置环境变量。该文件内容类似下面


SSH_AUTH_SOCK=/tmp/ssh-cBdruoAnh5/agent.5576; export SSH_AUTH_SOCK;
SSH_AGENT_PID=5578; export SSH_AGENT_PID;


$HOME/.ssh/environment并在当前shell设置此环境变量。

因此,第一次启动终端时,会提示你输入passphrase。但之后再启动新的终端时或在已有终端里进行ssh相关操作时,则不会再提示输入passphrase了。

.bashrc的改动仅限于私钥所在的机器(这里是本地机器homepc),因为只有在此机器才有必要启动ssh-agent。在登陆的远端机器(server)上是不需要启动ssh-agent的,因此对该远端机器的.bashrc不要做此改动。$SSH_AUTH_SOCK环境变量的。只要在ssh登陆时加上了-A参数打开agent forwarding,则登陆成功后会自动在目标机器的shell中设置此环境变量。

下面的例子, homepc上设置好了ssh-agent, 只要路径上一直保持打开agent forwarding,所有随后的级联登陆都不需要输入passphrase.



yourname@homepc:~$ echo $SSH_AUTH_SOCK # ssh client会通过它和homepc的ssh-agent通信
/tmp/ssh-UNJHj21949/agent.21949
yourname@homepc:~$ ssh -A server
yourname@server:~$ ssh -A server2
yourname@server2:~$ ssh -A server3
yourname@server3:~$ echo $SSH_AUTH_SOCK # ssh client会通过它和server3的sshd通信, server3并没有启动ssh-agent
/tmp/ssh-MhVpVs1071/agent.1071



windows securecrt 配置

如果工作机器是windows,则登陆到远端机器工作最方便的terminal是securecrt。在securecrt上配置公钥认证登陆和打开agent forwarding所做的底层工作其实是一样的,只是配置方式不同而已(需通过GUI来配置)。具体需要配置的地方如下

  1. 选项 > 全局选项 > SSH2
  • 使用身份或证书中 配置私钥(id_rsa)的路径
  • 高级中选中 添加密要到代理程序和启用OpenSSH代理程序转发


agentlib address参数 agent forwarder_环境变量

  1. 新建的连接属性 > 鉴权, 将公钥选项选中并设置为第一个选项