[Linux] 使用expect批量配置服务器间免密钥登录

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 [email protected]
[email protected]'s password:
Now try logging into the machine, with "ssh '[email protected]'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

[root@xxx .ssh]# ssh [email protected]
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 [email protected]
[email protected]'s password:   => 从A登录B需要提供密码

[root@xxx test]# ssh [email protected]
[email protected]'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 [email protected]
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 [email protected]
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]#

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章