zhangguanzhang's Blog

ssh互信

字数统计: 687阅读时长: 3 min
2017/05/12

ssh公钥免密码登录

ssh-trust

ssh-keygen 命令用来生成公钥和私钥密钥对的工具,通常用法是 -t 指定加密算法, -f指定输出路径,一般是 ~/.ssh/id_rsa-P 是指定私钥密码

1
2
3
4
5
6
7
[root@guan ~]# ssh-keygen -t rsa    # -t参数指定算法,可以是rsa或dsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): # 询问私钥保存路径
Enter passphrase (empty for no passphrase): # 询问是否加密私钥文件
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.

如果不想被询问,则可以使用下面一条命令完成:”-f”指定私钥文件,”-P”指定passphrase,或者”-N”也一样。

1
2
# 指定加密私钥文件的密码为空密码,即不加密
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''

然后用 ssh-copy-id 分发公钥,ssh-copy-id 用法很简单,只需指定待信任主机及目标用户即可。如果生成的公钥文件,路径不是 ~/.ssh/id_rsa.pub,则使用”-i”选项指定要分发的公钥。
例如分发到192.168.1.105上

1
2
$ ssh-copy-id -i ~/.ssh/id_rsa.pub -p 22 192.168.1.105
root@192.168.1.105's password: #输入目标主机密码即可

ssh-copy-id 唯一需要注意的是,如果 ssh 服务端的端口不是 22,则需要给 ssh-copy-id 传递端口号,传递方式为-p port_num [user@]hostname,例如-p 22222 root@172.16.10.6。之所以要如此传递,见下面摘自 ssh-copy-id 中公钥分发的命令部分。

1
{ eval "$GET_ID" ; } | ssh $1 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys && (test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh/authorized_keys >/dev/null 2>&1 || true)" || exit 1

其中 { eval "$GET_ID" ; } 可理解为待分发的本地公钥内容,(test -x /sbin/restorecon && /sbin/restorecon ~/.ssh ~/.ssh/authorized_keys >/dev/null 2>&1 || true) 和 selinux 有关,不用管,所以上述命令简化为:

1
cat ~/.ssh/id_rsa.pub | ssh $1 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys || exit 1

可见,ssh-copy-id的所有参数都是存储在位置变量 $1 中传递给 ssh,所以应该将ssh的端口选项-p port_numuser@hostname放在一起传递。

通过分析上面的命令,也即知道了 ssh-copy-id 的作用:在目标主机的指定用户的家目录下,检测是否有~/.ssh目录,如果没有,则以 700 权限创建该目录,然后将本地的公钥追加到目标主机指定用户家目录下的 ~/.ssh/authorized_keys 文件中。

-o StrictHostKeyChecking=no可以跳过证书验证,配合 sshpass 即可满足所有情况,否则初次的证书的 yes 得由 expect 脚本处理

CATALOG