1.两台服务器间免密钥登录
假设有两台服务器A和B,
1)单向免密钥(例如从A登录B无需提供密码):
服务器A使用命令ssh-keygen -t rsa生成本用户的id_rsa,追加到服务器B目标用户的 ~/.ssh/authorized_keys中
2)双向免密钥:
服务器A使用命令ssh-keygen -t rsa生成本用户的id_rsa,追加到服务器B目标用户的 ~/.ssh/authorized_keys中
服务器B使用命令ssh-keygen -t rsa生成本用户的id_rsa,追加到服务器A目标用户的 ~/.ssh/authorized_keys中
以单向免密钥说明,具体步骤如下,
假设配置的是从服务器A的root用户到服务器B的root用户的免密钥登录,即以root用户登录A,再从A的环境登录到B无需提供密码
step 1 生成服务器A的密钥
以root用户登录A,执行ssh-keygen -t rsa,收到提示信息按回车(共3次),会生成两个文件 id_rsa和id_rsa.pub
说明:注意看以下打屏的输出提示,
Enter file in which to save the key (/root/.ssh/id_rsa): => 该步骤按回车,以上两个文件生成在/root/.ssh/
Enter passphrase (empty for no passphrase): => 该步骤按回车,不提供密码
以上等价于执行ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
参数说明:
-t 指定要生成的密钥类型,默认是rsa,可省略
-P 提供的密码(passphrase), "" 表示没有
-f 指定密钥生成后的保存文件位置
[root@xxx .ssh]# ssh-keygen -t rsa
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.
The key fingerprint is:
d5:de:f1:36:50:bf:cc:83:52:de:31:ee:41:25:c2:8d root@xxx
The key's randomart image is:
+--[ RSA 2048]----+
| ..o...|
| .E.o.o|
| . .o.+.|
| . .o.Oo+|
| S ..o.Xo|
| . ..+|
| . |
| |
| |
+-----------------+
[root@xxx .ssh]# ls -l
total 16
-rw-------. 1 root root 1675 Mar 6 09:44 id_rsa
-rw-r--r--. 1 root root 394 Mar 6 09:44 id_rsa.pub
-rw-r--r--. 1 root root 5269 Dec 4 13:55 known_hosts
[root@xxx .ssh]#
step 2 将服务器A的公钥id_rsa.pub发送到服务器B的~/.ssh/authorized_keys
服务器A,xxx,192.168.11.11
服务器B,aaa,192.168.22.22
可以简单地使用命令ssh-copy-id,并验证A到B可以免密钥登录,如下,
[root@xxx .ssh]# ssh-copy-id root@192.168.22.22
root@192.168.22.22's password:
Now try logging into the machine, with "ssh 'root@192.168.22.22'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
[root@xxx .ssh]# ssh root@192.168.22.22
Last login: Fri Mar 6 09:30:15 2020 from 169.144.160.248
[root@aaa ~]#
说明:这步操作会将服务器A的公钥(刚才在A生成的id_rsa.pub)追加到服务器B的文件~/.ssh/authorized_keys中(若该文件不存在会去创建),查看服务器B上的authorized_keys多了一条记录。
[root@aaa .ssh]# cat authorized_keys
ssh-rsa AAAAB3NzaC1yc2E9X+JKOhtCJQl8y+QnWrZH3bJAcJr4hICuCpMAS+lyNuvHDODHcF6XuU1SwS0gN2aOW8prvBYdRJeB+7T7dRyL1ntX4j2XIsjb03XCuwsJgxfpYlZh0bUR8Wrq9EtuPExqDpbC3GKAoEl4SbAAAABIwAAAQEAx0IJQxyXecAHbbismwYXPpdCazEQlWlSmzRtMTEF2x/cuI07iqCz/U+vcwCLwbFYag9A08Ayu4QwAx5EShzbRhBDVt8/fqjTFHH81tKVjsXEOVt8BwYy3EV8L+Pactcbg3wZj2LIUvkcwfNqk2ZFR10d9fIO3W+73Wzg67MITdPf58R6/bg5XL9DNxIFem0EhKrzm8w== root@xxx
[root@aaa .ssh]#
该步骤等价于将A的id_rsa.pub重命名为id_rsa_xxx.pub => 传输id_rsa_xxx.pub至服务器B => 将id_rsa_xxx.pub的内容追加到B的authorized_keys。
2.结合expect批量设置单台服务器免密钥登录其它多台服务器
现有三台服务器A,B,C。A作为管理员的角色,需要能免密钥登录其它两台服务器。可以结合except使用脚本实现。
服务器A,xxx,192.168.11.11
服务器B,aaa,192.168.22.22
服务器C,bbb,192.168.33.33
1) 执行脚本前测试:A不能免密钥登录B和C
[root@xxx test]# ssh root@192.168.22.22
root@192.168.22.22's password: => 从A登录B需要提供密码
[root@xxx test]# ssh root@192.168.33.33
root@192.168.33.33's password: => 从A登录B需要提供密码
[root@xxx test]#
2) hostslist中记录服务器列表,按列依次表示IP地址、用户名、密码,示例内容如下
192.168.22.22 root iam22
192.168.33.33 root iam33
3) copyRsapub.sh内容如下
#!/bin/bash
#判断是否存在密钥,没有则生成
if [ ! -f ~/.ssh/id_rsa ];then
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
else
echo "id_rsa already exists."
fi
#将公钥分发到各个节点
while read line
do
#获取各个节点的登录信息
user=`echo $line | cut -d " " -f 2`
ip=`echo $line | cut -d " " -f 1`
passwd=`echo $line | cut -d " " -f 3`
expect <<EOF
#注意:如果登录节点较慢而超时,需要调大超时时间
set timeout 20
spawn ssh-copy-id $user@$ip
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$passwd\n" }
}
expect "password" { send "$passwd\n" }
EOF
done < hostslist
说明:
1.shell脚本中调用expect,形如
expect <<EOF
#将expect语句写在这之间
EOF
2.while read line结构
while read line
do
…
done < filename
其中filename是一个文件,可以是显式的文件;也可以是类似$1的参数,然后执行脚本时传入文件。
read通过输入重定向,把file的第一行所有的内容赋值给变量line,循环体内的命令对变量line进行处理;然后循环处理file的第二行、第三行……直到最后一行。
4)执行chmod 755 copyRsapub.sh; ./copyRsapub.sh
5) 执行脚本后测试:A能够免密钥登录B和C
[root@xxx test]# ssh root@192.168.33.33
Last login: Fri Mar 6 09:28:29 2020 from 192.168.11.11
[root@bbb ~]# exit => 从A登录B无需提供密码
logout
Connection to 192.168.33.33 closed.
[root@xxx test]# ssh root@192.168.22.22
Last login: Fri Mar 6 09:35:17 2020 from 192.168.11.11
[root@aaa ~]# exit => 从A登录C无需提供密码
logout
Connection to 192.168.22.22 closed.
[root@xxx test]#