按照慣例先報一下運行環境:實體機ubuntu 12.04.3 LTS
shell使用GNU bash,版本爲4.2.25
需求:ssh免驗證登陸。
首先說明一下,這裏用發起ssh連接的客戶端稱爲C,接受連接的服務端稱爲S,結合需求簡單來說就是從C發起ssh連接到S通過公私鑰配對驗證,免去手動輸入密碼驗證。除了需要在客戶端C上使用ssh-keygen命令生成密鑰對之外,還需要把生成的公鑰拷貝到服務端S中,而ssh命令集存在一個命令ssh-copy-id可以指定公鑰文件併發送到指定服務端中,在這裏我使用了默認生成的私鑰和公鑰文件名,即id_rsa和id_rsa.pub。而生成密鑰對文件的過程中會產生交互操作,所以要實現無人值守批量操作的話需要用到expect這個shell腳本的擴展方法來進行交互操作,expect有自己一套語法,具體可以自己百度。
首先是批量實現ssh免驗證登陸腳本keygenSCdi.sh:
#!/usr/bin/expect //聲明腳本解釋器,由此可見這是一個expect腳本
#deliver the key gen sc to clinet
#keygenSCdi.sh
#author:drowsc
set iplist [open [lindex $argv 0] ] //設定變量iplist從第一個參數傳遞的外部文件讀入
set cmdfile [open [lindex $argv 1] ]
set password "bita\r"
set timeout 10
while {[gets $iplist ip] >0} { //獲取iplist變量的值並賦值給變量ip,判斷獲得的ip地址個數是否大於0
seek $cmdfile 0
spawn ssh -p36000 bita@$ip //依次遠程登錄每個客戶端
for {} {1} {} {
expect {
"password:" {send "$password"} //出現密碼輸入提示自動輸入密碼$password
"$" {
while { [gets $cmdfile c] > 0 } {
send "$c\r" ; //傳遞任務文件cmdfile裏的內容並執行
expect {
"yes/no)?" { send "yes\r"; exp_continue } //當客戶端回顯的結果出現“yes/no)?"的時候應答"yes”並回車
"password:" { send "$password" }
}
}
expect "$"
break //執行完任務後跳出for循環並開始連接下一個客戶端
}
timeout {puts "timeout";break}//響應超時設置
}
}
}
close $iplist //關閉變量iplist從傳參獲取的文件內容
close $cmdfile
echo "all key gen complete!!"
接着是使用expect腳本所需的前提,批量給客戶機安裝expect方法expect_install.sh:
#!/bin/bash
#!/usr/bin/expect
#for install expect funtion on client
#expect_install.sh
#author:drowsc
bitadir=/home/bita/ //設定目錄變量
workdir=/home/bita/bisc
for ip in $(cat $workdir"/iplist.txt") //獲取iplist.txt裏的ip地址並逐一取值賦給變量ip,然後開始循環
do
ssh -p36000 bita@$ip << EOF
echo "bita" | sudo -S apt-get -y install expect//使用apt-get安裝expect
exit
EOF
done
echo "expect install finished!!!"
附所執行的任務文件cmdfile.txt:
echo "bita"|sudo -S chown bita.bita /home/bita/.ssh
ssh-keygen -t rsa -P '' -f /home/bita/.ssh/id_rsa > /dev/null //在指定路徑生成密鑰對
cd /home/bita/.ssh
ssh-copy-id "-p 36000 [email protected]" //使用ssh-copy-id命令把默認情況下/home/user/.ssh/目錄下的id_rsa.pub公鑰文件發出到指定主機的默認ssh密鑰存放目錄
PS:一.查看當前linux的發行版本方法有1:gnome-system-monitor 2.uname -a(通常查內核版本) 3.cat /etc/ubuntu(發行版本名稱)-release 4.cat /etc/issue
二.查看當前使用的shell:1. ps |grep $$|awk '{print $4}'//不帶參數的ps命令顯示和當前終端有關的進程狀況
//$$變量存儲當前進程的PID
//ps第四列是進程所使用的命令,如果是Shell,那麼顯示shell名,比如sh/ksh等
//awk '{print $4}'就是隻顯示第四列的值
三.find -name *.txt -exec cat {} \; //選項-exec可以爲find的結果提供後續操作,此處的{} \代表find所得到的結果
四.關於ssh建立握手驗證:一般首次進行ssh登陸時的yes/no是提示是否進行特徵碼生成並記錄到~/.ssh/known_hosts中,若重新使用ssh-keygen生成祕鑰則本機生成的新特徵碼則會跟舊特徵碼不匹配,導致ssh連接時產生安全報錯,此時只要根據錯誤信息提示刪除對應特徵碼記錄即可重新進行驗證。