1. 程式人生 > >ssh原理及管理機分發公鑰方法

ssh原理及管理機分發公鑰方法

ssh原理:在SSH安全協議的原理中, 是一種非對稱加密與對稱加密演算法的結合。

ssh登入有2種方法:賬號密碼登入和公鑰登入。

1.帳號密碼登入,沒辦法公證,不像https有CA證書公證。

image.png

1.服務端收到登入請求後,首先互換公鑰。

2.客戶端用服務端的公鑰加密賬號密碼併發送

3.服務端用自己的祕鑰解密後得到賬號密碼,然後進行驗證

4.服務端用客戶端的公鑰加密驗證結果並返回

5.客戶端用自己的祕鑰解密後得到驗證結果


2.ssh免密碼登入,利用公鑰登入

image.png

步驟:

1.客戶端使用者必須手動地將自己的公鑰新增到伺服器一個名叫authorized_keys的檔案裡,顧名思義,這個檔案儲存了所有可以遠端登入的機器的公鑰。

2.客戶端發起登入請求,並且傳送一個自己公鑰的指紋(具有唯一性,但不是公鑰)

3.服務端根據指紋檢測此公鑰是否儲存在authorized_keys中

4.若存在,服務端便生成一段隨機字串,然後利用客戶端公鑰加密並返回

5.客戶端收到後用自己的私鑰解密,再利用服務端公鑰加密後發回

6.服務端收到後用自己的私鑰解密,如果為同一字串,則驗證通過


分發金鑰方法:

1.使用ssh分發

[[email protected] ~]# ssh-keygen -t dsa -P '指定密碼' -f ~/.ssh/id_dsa >/dev/null 2>&1
[
[email protected]
 ~]# /usr/bin/ssh-copy-id  -i .ssh/id_dsa.pub [email protected] 測試 [[email protected] ~]# ssh [email protected] Last login: Wed Nov  7 14:29:38 2018 from 192.168.146.140 [[email protected]
 ~]#

注意:金鑰是針對使用者的,可以使用其他使用者建立金鑰,在被管理機器上也需要有相同的使用者。

ssh-keygen命令:

man ssh-keygen:authentication key generation, management and conversion 金鑰生成、管理、轉換
選項:
-t type:指定金鑰型別,包括“dsa”, “ecdsa” or “rsa”
-p(小) :更改私鑰的密碼。程式會提示輸入私鑰的密碼以及2次新密碼
-P(大):提供私鑰的舊密碼。
-N:提供私鑰的新密碼
-f :指定金鑰檔案的檔名
-b:指定金鑰長度
-e:讀取openssh的私鑰或者公鑰檔案

ssh-copy-id命令:

man ssh-copy-id :install your public key in a remote machine’s authorized_keys 安裝公鑰到遠端機器的authorized keys.
語法:ssh-copy-id [-i [identity_file]] [[email protected]]machine
選項:-i 指定要分發的公鑰

2.使用expect解決互動式分發

expect指令碼中常見命令:spawn, expect, send, interact...

spawn開啟一個程序

expect該命令從程序接受字串,如果接受的字串和期待的字串不匹配,則一直阻塞,直到匹配上或者等待超時才繼續往下執行

send向程序傳送字串,與手動輸入內容等效,通常字串需要以’\r’結尾

expect{"匹配字元" send {"需要傳送的"} 
"匹配字元"send{"需要傳送的字元"}}
或者
expect "匹配字元" 
send "傳送字元\r"

interact該命令將控制權交給控制檯,之後就可以進行人工操作了。通常用於使用指令碼進行自動化登入之後再手動執行某些命令。如果指令碼中沒有這一條語句,指令碼執行完將自動退出。

set timeout 30 設定超時時間timeout為30s,expect命令阻塞超時時會自動往下繼續執行。將timeout配置為-1時表示expect一直阻塞直到與期待的字串匹配上才繼續往下執行。超時時間timeout預設為10s

[lindex $argv n]可以在指令碼中使用該命令獲取在指令碼執行時傳入的第n-1個引數。argv為傳入的引數,另外argc表示傳入引數的個數,n是從0開始,表示第一個引數..n=1表示第二個引數

exp_continue:繼續執行下面匹配

\r:linux下的回車,Windows下回車是\r\n

安裝

[[email protected] ~]# yum install expect   #安裝expect ,需要安裝依賴包tcl

獨立expect指令碼

[[email protected] ~]# cat /server/script/ssh_expect.exp
#!/usr/bin/expect

set timeout 30
set ip [lindex $argv 0]                    #第1個引數,編號是0
set password [lindex $argv 1]              #第2個引數,編號是1  

spawn ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]$ip
expect {
         "(yes/no)?"  {send "yes\r";exp_continue}
         "password:" {send "$password\r"}
}
expect eof
[[email protected] ~]# expect /server/script/ssh_expect.exp 192.168.146.136 111111    #192是第1個引數,編號是0 111111是第2個引數,編號是1*****
spawn ssh-copy-id -i /root/.ssh/id_dsa.pub [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.

[[email protected] ~]# ssh [email protected]
Last login: Wed Nov  7 16:46:46 2018 from 192.168.146.140
[[email protected] ~]# logout
Connection to 192.168.146.136 closed.
[[email protected] ~]#

實現自動分發,無需手動輸入ip及密碼,將expect程式巢狀在shell指令碼

[[email protected] ~]# cat /server/script/Auto-fenfa.exp
#!/bin/bash
#Create by 海中小帆船
#Date 2018-11-08
#Functions Auto fenfa miyao
#Version 1.1
key_file='/root/.ssh/id_dsa.pub'
password='Y3^K2&123&'
[ ! -e $key_file ] && ssh-keygen -t dsa -P '' -f /root/.ssh/id_dsa > /dev/null 2>&1

for ip in {136..139}
do
/usr/bin/expect << EOF > /dev/null 2>&1
spawn ssh-copy-id -i $key_file "-p22 [email protected]$ip"
expect {
        "yes/no" {send "yes\r";exp_continue}
        "password" {send "$password\r"}
}
expect eof
EOF
if [ $? -eq 0 ]
        then
echo "192.168.146.$ip 金鑰分發完成"
        else
echo "192.168.146.$ip 金鑰分發失敗"
fi
done
[[email protected] ~]# sh /server/script/Auto-fenfa.exp
192.168.146.136 金鑰分發完成
192.168.146.137 金鑰分發完成
192.168.146.138 金鑰分發完成
192.168.146.139 金鑰分發完成

建立金鑰、分發金鑰、批量上傳指令碼、批量執行指令碼

[[email protected] script]# cat Q-auto-bushu.sh
#!/bin/bash
#Create By QQ
#Date ***
#Functions ****
#Version 1.1
#########################1.建立金鑰##################
. /etc/init.d/functions
[ ! -e "/root/.ssh/id_dsa.pub" ] && ssh-keygen -t dsa -P '' -f /root/.ssh/id_dsa >/dev/null 2>&1
if [ $? -eq 0 ];then
        action "建立金鑰成功" /bin/true
else
        action "建立金鑰失敗" /bin/false
        exit 0
fi

######################2.分發金鑰####################
for ip in 192.168.146.{136..139}
do
/usr/bin/expect << EOF > /dev/null 2>&1
spawn ssh-copy-id -i /root/.ssh/id_dsa.pub "-p22 $ip"
expect {
        "yes/no" {send "yes\r";exp_continue}
        "password" {send "111111\r"}
}
expect eof
EOF
if [ $? -eq 0 ];then
        action "$ip分發金鑰完成" /bin/true
else
        action "$ip分發金鑰失敗" /bin/false
fi
done
#######################3.傳送安裝指令碼###############
for i in 192.168.146.{136..139}
do
 scp /server/script/install_man.sh [email protected]$i:/server/script/
 if [ $? -eq 0 ];then
        action "$i傳送安裝指令碼成功" /bin/true
 else
        action "$i傳送安裝指令碼失敗" /bin/false
 fi
done
######################4.遠端安裝指令碼################
for n in 192.168.146.{136..139}
do
 ssh [email protected]$n /bin/bash /server/script/install_man.sh
 if [ $? -eq 0 ];then
                action "$n安裝man完成" /bin/true
        else
                action "$n安裝man失敗" /bin/false
 fi
done
[[email protected] script]#

測試結果

[[email protected] script]# sh Q-auto-bushu.sh
建立金鑰成功                                         [  OK  ]
192.168.146.136分發金鑰完成                                 [  OK  ]
192.168.146.137分發金鑰完成                                 [  OK  ]
192.168.146.138分發金鑰完成                                 [  OK  ]
192.168.146.139分發金鑰完成                                 [  OK  ]
192.168.146.136傳送安裝指令碼成功                                 [  OK  ]
192.168.146.137傳送安裝指令碼成功                                 [  OK  ]
192.168.146.138傳送安裝指令碼成功                                 [  OK  ]
192.168.146.139傳送安裝指令碼成功                                 [  OK  ]
192.168.146.136安裝man完成                                 [  OK  ]
192.168.146.137安裝man完成                                 [  OK  ]
192.168.146.138安裝man完成                                 [  OK  ]
192.168.146.139安裝man完成                                 [  OK  ]
[[email protected] script]#
[[email protected] ~]# which man
/usr/bin/man