[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]#

 

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