天天看點

linux免互動登陸遠端主機并執行指令(密鑰對和Expect)

linux下實作免互動登陸一般有兩種:

1. ssh無密碼認證方式

    用戶端使用ssh-keygen生成密鑰對,将公鑰複制到服務端(authorized_keys),ssh提供公鑰登陸,當ssh通路服務端時,服務端先在本機尋找用戶端的公鑰,然後把用戶端發來的公鑰進行比較,如果一緻,則用公鑰加密給用戶端,用戶端再用私鑰進行解密,實作加密所有傳輸的資料。

1>.在客戶機上建立密鑰對

# ssh-keygen -t rsa #一路回車

2>.登陸ssh伺服器,建立.ssh目錄及設定權限

1

2

<code># mkdir /root/.ssh</code>

<code># chmod 700 /root/.ssh</code>

3&gt;.将公鑰上傳到伺服器并重命名為authorized.keys

<code># scp /root/.ssh/id_rsa.pub root@服務端ip:/root/.ssh/authorized_keys #id_rsa.pub可以追加多個用戶端的公鑰</code>

4&gt;.設定ssh伺服器

3

4

5

6

<code># vi /etc/ssh/sshd_config </code>

<code>rsaauthentication </code><code>yes</code>           <code>#這三行取消注釋,開啟密鑰對驗證</code>

<code>pubkeyauthentication </code><code>yes</code>

<code>authorizedkeysfile .</code><code>ssh</code><code>/authorized_keys</code>

<code>passwordauthentication no    </code><code>#關閉密碼驗證</code>

<code># service sshd restart</code>

5&gt;.免互動登陸測試,并檢視遠端主機磁盤分區

<code># ssh root@服務端ip 'df -h'</code>

2. 利用expect工具自動實作互動任務

   expect是一個免費的程式設計工具語言,用來實作自動和互動式任務進行通信,而無需人的幹預。

   centos安裝:yum install expect

   ubuntu安裝:sudo apt-get install expect

1&gt;.免互動登陸,檢視遠端主機磁盤分區

7

8

9

10

11

12

13

<code>#!/usr/bin/expect</code>

<code>set</code> <code>ip 192.168.1.156</code>

<code>set</code> <code>pass 123.com    </code>

<code>set</code> <code>timeout 30</code>

<code>spawn </code><code>ssh</code> <code>root@$ip</code>

<code>expect {</code>

<code>        </code><code>"(yes/no)"</code> <code>{send </code><code>"yes\r"</code><code>; exp_continue}</code>

<code>        </code><code>"password:"</code> <code>{send </code><code>"$pass\r"</code><code>}</code>

<code>}</code>

<code>expect </code><code>"root@*"</code>  <code>{send </code><code>"df -h\r"</code><code>}</code>

<code>expect </code><code>"root@*"</code>  <code>{send </code><code>"exit\r"</code><code>}</code>

<code>expect eof</code>

<code># interact</code>

2&gt;.在shell腳本中嵌入expect文法

 方法1:使用eof,将内容段讓expect執行

14

15

<code>#!/bin/bash</code>

<code>user=root</code>

<code>pass=</code><code>'123'</code>

<code>ip=</code><code>'192.168.1.154'</code>

<code>/usr/bin/expect</code> <code>&lt;&lt; eof</code>

<code>spawn </code><code>ssh</code> <code>$user@$ip   </code>

<code>expect eof </code>

<code>eof</code>

<code>expect -c "</code>

<code>    </code><code>spawn </code><code>ssh</code> <code>$user@$ip</code>

<code>    </code><code>expect {</code>

<code>        </code><code>\"(</code><code>yes</code><code>/no</code><code>)\" {send \"</code><code>yes</code><code>\r\"; exp_continue}</code>

<code>        </code><code>\"password:\" {send \"$pass\r\"; exp_continue}</code>

<code>        </code><code>\"root@*\" {send \"</code><code>df</code> <code>-h\r </code><code>exit</code><code>\r\"; exp_continue}</code>

<code>    </code><code>}"</code>

方法2:将expect腳本獨立出來

16

17

18

<code># vi login.exp      #免互動登陸腳本</code>

<code>#!/usr/bin/expect </code>

<code>set</code> <code>ipaddress [lindex $argv 0]</code>

<code>set</code> <code>username [lindex $argv 1]</code>

<code>set</code> <code>password [lindex $argv 2]</code>

<code>if</code> <code>{ $argc != 3 } {</code>

<code>puts </code><code>"usage: expect login.exp ipaddress username password"</code>

<code>exit</code> <code>1</code>

<code>spawn </code><code>ssh</code> <code>$username@$ipaddress</code>

<code>        </code><code>"password:"</code> <code>{send </code><code>"$password\r"</code><code>}</code>

<code>expect </code><code>"$username@*"</code>  <code>{send </code><code>"df -h\r"</code><code>}</code>

<code>expect </code><code>"$username@*"</code>  <code>{send </code><code>"exit\r"</code><code>}</code>

<code># vi user_info     #使用者資訊檔案</code>

<code>192.168.1.156   user    user</code>

<code>192.168.1.154   root    123.com</code>

<code># vi expect.sh     #讀取使用者資訊并指派到變量</code>

<code>for</code> <code>ip </code><code>in</code> <code>`</code><code>awk</code> <code>'{print $1}'</code> <code>user_info`</code>

<code>do</code>

<code>    </code><code>user=`</code><code>awk</code> <code>-</code><code>v</code> <code>i=</code><code>"$ip"</code> <code>'{if(i==$1)print $2}'</code> <code>user_info`</code>

<code>    </code><code>pass=`</code><code>awk</code> <code>-</code><code>v</code> <code>i=</code><code>"$ip"</code> <code>'{if(i==$1)print $3}'</code> <code>user_info`</code>

<code>    </code><code>expect login.exp $ip $user $pass</code>

<code>done</code>

參數說明:

set:可以設定逾時,也可以設定變量

timeout:expect逾時等待時間,預設10s

spawn:執行一個指令

expect "":比對輸出的内容

exp_continue:繼續執行下面比對

\r:可以了解為回車

$argc:統計位置參數數量

[lindex $argv 0]:腳本後第一個參數,類似于shell中$1,以此類推

puts:列印字元串,類似于echo

awk -v i="$ip":指派變量

expect{...}:輸入多行記錄

其他參數說明:

timeout -1:永不逾時退出

log_file /var/log/expect.log:記錄互動資訊,一般crontab時使用

interact:互動後不退出遠端終端,如果加要把expect "root@*" {send "exit\r"}注釋掉,如果不加,就直接退出

将spawn ssh root@$ip換成spawn ssh -o stricthostkeychecking=no root@ip既不會再提示是否将伺服器計算機密鑰加入本地known_hosts

繼續閱讀