通過scp拷貝文件時無需交互輸入密碼


    工作中經常需要把一些文件從一個服務器傳輸到另一台服務器,linux環境下最習慣的方式當然是scp,但是scp需要交互輸入密碼有時候覺得麻煩,記錄幾種無需手動輸入密碼的方法。

方法一:建立SSH互信

    此方式不僅是方便scp,在可靠系統間此方式也是非常方便的連接方式,具體建立互信操作過程暫略,前面地方有單獨記錄過了。

 

方法二:使用sshpass工具

    建立信任關系的做法是最方便和安全的做法,但是在有些場景下(比如遠端的authorized_keys是不能隨意更改的),那么這個時候我們就可以借助sshpass這個第三方工具來完成ssh連接時的密碼輸入。先看一下sshpass的man手冊中是如何描述的:

    sshpass - noninteractive ssh password provider

    從描述上就可以清晰的了解到,sshpass的設計就是為了使用非交互的場景下輸入ssh連接的密碼。

    sshpass的使用比較簡單,先看一下幫助文檔:

    root@localhost:~# sshpass 
    Usage: sshpass [-f|-d|-p|-e] [-hV] command parameters
       -f filename   Take password to use from file
       -d number     Use number as file descriptor for getting password
       -p password   Provide password as argument (security unwise)
       -e            Password is passed as env-var "SSHPASS"
       With no parameters - password will be taken from stdin
       -h            Show help (this screen)
       -V            Print version information
    At most one of -f, -d, -p or -e should be used

    其中-p是直接指定密碼,-f是從文件中讀取密碼。那么一個使用sshpass的簡單例子就是:

    

[root@node1 ~]# sshpass -f pa.txt scp index root@192.168.10.22:/var
[root@node1 ~]# sshpass -p root1234 scp config.log root@192.168.10.22:/root/a.lo

  使用sshpass的好處就是方便直接,無需了解公私鑰、加密認證等相關知識,簡單易懂;但是使用sshpass最大的壞處就是在使用時會涉及到明文密碼,大大降低了安全性。

 

方式三:使用expect腳本來輸入密碼

    expect用於自動化地執行linux環境下的命令行交互任務,例如scp、ssh之類需要用戶手動輸入密碼然后確認的任務。有了這個工具,定義在scp過程中可能遇到的情況,然后編寫相應的處理語句,就可以自動地完成scp操作了。

    下面就是一個使用expect來完成scp時無需輸入密碼的腳本:

#!/usr/bin/expect  
set timeout 10  
set host [lindex $argv 0]  
set username [lindex $argv 1]  
set password [lindex $argv 2]  
set src_file [lindex $argv 3]  
set dest_file [lindex $argv 4]  
spawn scp $src_file $username@$host:$dest_file  
 expect {  
 "(yes/no)?"  
  {  
    send "yes\n"  
    expect "*assword:" { send "$password\n"}  
  }  
 "*assword:"  
  {  
    send "$password\n"  
  }  
}  
expect "100%"  
expect eof  

    意代碼剛開始的第一行,指定了expect的路徑,與shell腳本相同,這一句指定了程序在執行時到哪里去尋找相應的啟動程序。代碼剛開始還設定了timeout的時間為10秒,如果在執行scp任務時遇到了代碼中沒有指定的異常,則在等待10秒后該腳本的執行會自動終止。

    從以上代碼剛開始的幾行可以看出,我為這個腳本設置了5個需要手動輸入的參數,分別為:目標主機的IP、用戶名、密碼、本地文件路徑、目標主機中的文件路徑。如果將以上腳本保存為expect_scp文件,則在shell下執行時需要按以下的規范來輸入命令:

./expect_scp 192.168.10.21 root 123456 /root/src_file /root/dest_file 

    以上的命令執行后,將把本地/root目錄下的src_file文件拷貝到用戶名為root,密碼為123456的主機192.168.10.21中的/root下,同時還將這個源文件重命名為dest_file。

    spawn代表在本地終端執行的語句,在該語句開始執行后,expect開始捕獲終端的輸出信息,然后做出對應的操作。expect代碼中的捕獲的(yes/no)內容用於完成第一次訪問目標主機時保存密鑰的操作。有了這一句,scp的任務減少了中斷的情況。代碼結尾的expect eof與spawn對應,表示捕獲終端輸出信息的終止。

    使用expect需要了解的一點是:用expect速度會比較慢,因為需要等待返回的數據,然后輸入命令執行,沒有ssh密鑰登錄的快速。

 

    安全性和速度上考慮建立信任關系都是最佳的方法,至於在具體的環境中選擇什么根據實際情況來選擇。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM