几种方法来实现scp拷贝时无需输入密码
歡迎轉載!轉載時請注明出處:http://blog.csdn.net/nfer_zhuang/article/details/42646849
前言
我在工作中經常要將一些文件傳輸到另外一個服務器上,而且都是Linux的命令行環境,那么對于我來講scp就是最直接有效的方法了,其他諸如FTP、SMB以及Winscp這些有界面的文件傳輸工具到反而有些多余了。
使用過scp的都知道需要指定遠端服務器的帳號并手動輸入密碼,那么如何避免每次都需要輸入密碼這個操作呢?下面就給出兩種方案進行解決。
方法一:建立SSH的信任關系
在這里先介紹兩個概念:SSH公鑰(~/.ssh/id_rsa.pub)和公鑰授權文件(~/.ssh/authorized_keys),這兩個文件的作用具體可以參考ssh的man手冊:
?~/.ssh/id_rsa.pub
?? ??? ? Contains the public key for authentication.? These files are not sensitive and can (but need not) be readable by anyone.
?~/.ssh/authorized_keys
?? ??? ? Lists the public keys (DSA/ECDSA/RSA) that can be used for logging in as this user.? The format of this file is described in the sshd(8) manual page.? This file is not highly sensitive, but the recommended permissions are read/write for the user, and not accessible by others.
從描述中我們可以知道,~/.ssh/id_rsa.pub文件中包含了認證的公鑰信息,而且該文件可以被任何人讀取;而~/.ssh/authorized_keys文件中則列舉了登錄用戶的公鑰信息(換句話說就是使用這些公鑰信息可以登錄當前設備),而為了安全考慮,該文件一般建議只有本用戶可以有讀寫權限。
公鑰和私鑰
提到公鑰對應的就會有私鑰,在談這兩個概念之前我們先了解另外一組概念:加密和認證。
- 加密是對數據進行處理,添加保護信息,如果非法用戶得到被加密過的數據,也無法獲取到原始的有效數據內容,所以加密的重點在于數據的安全性。
- 認證是對數據進行處理,添加鑒權信息,如果在傳輸的過程中被非法篡改,接收方就會校驗失敗并丟棄該非法數據,所以認證的重點在于數據的合法性。
上面是從業務概念來上描述了加密和認證的區別,但是從具體技術實現上,認證使用的是加密中的非對稱加密算法來實現鑒權和認證的操作。
- 對稱加密算法在加密和解密時使用的是同一個秘鑰;
- 非對稱加密算法需要兩個密鑰來進行加密和解密,這兩個秘鑰是公開密鑰(public key,簡稱公鑰)和私有密鑰(private key,簡稱私鑰)。
下面就分別描述一下,采用非對稱算法(即使用公鑰和私鑰)的加密和認證各自的過程。
基于公鑰和私鑰的加密過程
有兩個用戶Alice和Bob,Alice想把一段數據加密后發送給Bob(注意這里強調的是數據的安全性),那么如何保證除了Bob之外的人即使竊取了數據也無法解密得到原始的數據?基于公鑰和私鑰的加密可以完成這個需求,具體流程如下:
基于公鑰和私鑰的認證過程
還是Alice和Bob,Alice想把一段數據發送給Bob(注意這里并不強調數據的安全性),當Bob收到數據時如何判斷該數據確實是Alic發送的且傳輸過程中沒有被篡改?基于公鑰和私鑰的認證可以完成這個需求,具體流程如下:
基于公鑰和私鑰的信任關系
了解了公鑰/私鑰以及加密/認證這些概念后,我們就可以在scp中使用公鑰/私鑰來建立一個信任關系,從而在數據傳輸時完成自動認證而無需輸入密碼。
所以這里的需要做的就是:
- User在A主機上需要創建一個公私鑰對
- 在B主機上,將User在A主機的公鑰加入到ssh的信任公鑰列表中(即公鑰授權文件)
創建公私鑰對
在Linux上使用ssh-keygen工具來生成公私鑰對,在man手冊中關于ssh-keygen工具的說明如下:
ssh-keygen : authentication key generation, management and conversion
?-t?? ?type
?? ? Specifies the type?? ?of key to create.? The possible?? ?values are 'rsa1' for protocol version 1 and 'dsa', 'ecdsa', 'ed25519', or 'rsa' for protocol version 2.
在上面提到了ssh-keygen支持rsa1、dsa、ecdsa、ed25519和rsa這幾種非對稱加密算法,其中最常用的就是RSA和DSA,比如使用RSA算法來生成公私鑰對的過程如下:
[plain] view plain copy將User在A主機的公鑰加入到ssh的信任公鑰列表中
將剛才創建的~/.ssh/id_rsa.pub文件中的內容拷貝添加到B主機上的~/.ssh/authorized_keys文件中(如果沒有則創建一個),這個時候就建立了一條A-->B的信任關系。注意這個信任關系是有方向性的,如果要建立從B-->A的信任關系,則操作步驟和上面的類似,只不過要反過來。
建立好信任關系后,這個時候使用任何ssh相關的工具則都無需輸入遠端的登陸密碼(如果在創建公私鑰對時輸入了密碼,那么這個時候還需要輸入這個密碼才能使用公私鑰對)。
方法二:使用sshpass工具來自動輸入密碼
其實上面的建立信任關系的做法是最方便和安全的做法,但是在有些場景下(比如遠端的authorized_keys是不能隨意更改的),那么這個時候我們就可以借助sshpass這個第三方工具來完成ssh連接時的密碼輸入。先看一下sshpass的man手冊中是如何描述的:
?????? sshpass - noninteractive ssh password provider
從描述上就可以清晰的了解到,sshpass的設計就是為了使用非交互的場景下輸入ssh連接的密碼。
sshpass的使用比較簡單,先看一下幫助文檔:
nfer@nfer-VirtualBox:~$ 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的簡單例子就是:
[plain] view plain copy使用sshpass的好處就是方便直接,無需了解公私鑰、加密認證等相關知識,簡單易懂;但是使用sshpass最大的壞處就是再使用時會涉及到明文密碼,大大降低了安全性。
方法三:使用expect腳本來自動輸入密碼
expect用于自動化地執行linux環境下的命令行交互任務,例如scp、ssh之類需要用戶手動輸入密碼然后確認的任務。有了這個工具,定義在scp過程中可能遇到的情況,然后編寫相應的處理語句,就可以自動地完成scp操作了。
下面就是一個使用expect來完成scp時無需輸入密碼的腳本:
[plain] view plain copy注意代碼剛開始的第一行,指定了expect的路徑,與shell腳本相同,這一句指定了程序在執行時到哪里去尋找相應的啟動程序。代碼剛開始還設定了timeout的時間為10秒,如果在執行scp任務時遇到了代碼中沒有指定的異常,則在等待10秒后該腳本的執行會自動終止。
從以上代碼剛開始的幾行可以看出,我為這個腳本設置了5個需要手動輸入的參數,分別為:目標主機的IP、用戶名、密碼、本地文件路徑、目標主機中的文件路徑。如果將以上腳本保存為expect_scp文件,則在shell下執行時需要按以下的規范來輸入命令:
spawn代表在本地終端執行的語句,在該語句開始執行后,expect開始捕獲終端的輸出信息,然后做出對應的操作。expect代碼中的捕獲的(yes/no)內容用于完成第一次訪問目標主機時保存密鑰的操作。有了這一句,scp的任務減少了中斷的情況。代碼結尾的expect eof與spawn對應,表示捕獲終端輸出信息的終止。
使用expect需要了解的一點是:用expect速度會比較慢,因為需要等待返回的數據,然后輸入命令執行,沒有ssh密鑰登錄的快速。
注:關于expect部分詳細請參考《shell結合expect寫的批量scp腳本工具》
總結
在本文中提供了三種方法來實現scp的時候無需輸入密碼的需求,從安全性和速度上考慮建立信任關系都是最佳的方法,至于在具體的環境中選擇什么則由你自己來決定。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的几种方法来实现scp拷贝时无需输入密码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: source, ~/.bashrc, ~
- 下一篇: Ruby元编程