Linux scp 免密码 传输文件
SCP的使用
背景介紹
最近項目是集群化部署(由 node1,node2,node3 三臺 CentOS 7.4 的虛擬機構成)。
但是,涉及到跨機器同步文件的問題,想通過寫shell文件實現,用 crontab 設置定時任務,定時執行改腳本。
由于每次都需要輸入密碼,導致定時任務沒法正常工作,因此,需要三臺機器之間可以免密碼互相訪問。
建立SSH的信任關系
以實現 node1 免密碼給 node2 scp傳輸文件為例說明,需要如下幾個步驟:
1、生成 node1 的秘鑰(私鑰和公鑰)
1)進入 node1 的 /root/.ssh 目錄
cd /root/.ssh/2)執行如下命令,生成公鑰和私鑰(此時,一路回車即可)
ssh-keygen -t rsa
其中,id_rsa 是私鑰,id_rsa.pub 是公鑰。
2、將 node1 的 id_rsa.pub中的內容追加到 node2 的authorized_keys 認證文件中
1)將 node1 的公鑰(id_rsa.pub)信息,輸出到臨時認證文件 authorized_keys_node1 中
cat id_rsa.pub >authorized_keys_node1
2)將 authorized_keys_node1 文件 scp 到 /root/.ssh/ 目錄下
3)登錄到node2節點,進入 /root/.ssh目錄
4)將 node1 的公鑰信息,追加到 node2 的認證文件(authorized_keys)中
cat authorized_keys_node1 >>authorized_keys至此,node1 到 node2 的信任關系建立好了,node1 scp文件到 node2,就不在需要輸入密碼驗證了。
其他機器之間的信任關系,如有需要,可以依此方法進行配置。
注意: 授權列表authorized_keys可以追加多臺電腦的公鑰(id_rsa.pub), 讓多臺電腦免密碼驗證
【額外說明】
1、上面用到了 Shell 的 > 和 >>,因為使用場景不同。
如有不清楚二者異同點的同學,可以參考博文:https://blog.csdn.net/qq_43248623/article/details/107850758
2、文中提到的 id_rsa 和 id_rsa.pub 中的 rsa,是指的 RSA加密算法。
RSA加密算法是一種非對稱加密算法。在公開密鑰加密和電子商業中RSA被廣泛使用。RSA是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。
對極大整數做因數分解的難度決定了RSA算法的可靠性。換言之,對一極大整數做因數分解愈困難,RSA算法愈可靠。假如有人找到一種快速因數分解的算法的話,那么用RSA加密的信息的可靠性就肯定會極度下降。但找到這樣的算法的可能性是非常小的。今天只有短的RSA鑰匙才可能被強力方式解破。到目前為止,世界上還沒有任何可靠的攻擊RSA算法的方式。只要其鑰匙的長度足夠長,用RSA加密的信息實際上是不能被解破的。
詳細解答部分:
預備知識
在介紹SCP協議之前,我們先得了解一下SSH協議,和計算機中的加密方式,因為SCP協議的登錄過程基于SSH協議。
對稱加密
對稱加密,即在數據傳輸過程中對數據進行加密和解密的算法使用同一個密鑰,這種加密算法有什么弊端呢?
當客戶端需要與服務器端進行數據傳輸時,不管是由客戶端還是由服務端產生的密鑰,都得將這個密鑰傳給對方才能實現加解密,而在傳輸的過程中就可能造成密鑰的泄漏。
那么有些人就要說了,那我不用網絡傳輸秘鑰,我可以使用口頭傳輸或者u盤拷貝的方法。
是的,這樣就可以保證安全,但是在大多數互聯網應用中,通信雙方是陌生設備,無法做到上述的方式。
非對稱加密
針對對稱加密帶來的風險,非對稱加密則解決了這個問題。
將加解密使用的密鑰分為公鑰和私鑰,公鑰可以公開,而私鑰則由密鑰生成者保存,客戶端使用公鑰進行加密,而服務端用私鑰進行解密,且目前來說還沒有出現能從公鑰推算出私鑰的的破解機制。
所以相對于對稱加密而言,這種加密方式更加安全,但是這種加密方式的缺點是會占用更多的計算機資源,而且這種資源的耗費量是巨大的。
常見的加密方式
對稱加密:
DES(Data Encryption Standard):加密速度較快,適合加密大量數據的場合。
3DES:基于DES的加密算法,顧名思義,這是對一塊數據用三個不同的密鑰進行三次加密,顯而易見強度更高,更安全。
RC2和RC4:用變長密鑰對大量數據進行加密,速度比DES更快
IDEA:(International Data Encryption Algorithm)國際數據加密算法,使用 128 位密鑰提供非常強的安全性;
AES:高級加密標準,是下一代的加密算法標準,速度快,安全級別高,這個加密算法被廣泛應用。
非對稱加密:
RSA:是一個支持變長密鑰的公共密鑰算法,需要加密的文件塊的長度也是可變的,目前使用最廣的加密算法
Diff ieˉHellman:每次交換數據的時候都使用一組新的密鑰,有效地防止了第三方獲得私鑰后解密所有信息,但是同時對中間人攻擊的防護比較薄弱。
非對稱加密算法是一種密鑰的保密方法。
???????非對稱加密算法需要兩個密鑰:公開密鑰(publickey:簡稱公鑰)和私有密鑰(privatekey:簡稱私鑰)。公鑰與私鑰是一對,如果用公鑰對數據進行加密,只有用對應的私鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。 非對稱加密算法實現機密信息交換的基本過程是:甲方生成一對密鑰并將公鑰公開,需要向甲方發送信息的其他角色(乙方)使用該密鑰(甲方的公鑰)對機密信息進行加密后再發送給甲方;甲方再用自己私鑰對加密后的信息進行解密。甲方想要回復乙方時正好相反,使用乙方的公鑰對數據進行加密,同理,乙方使用自己的私鑰來進行解密。
???????另一方面,甲方可以使用自己的私鑰對機密信息進行簽名后再發送給乙方;乙方再用甲方的公鑰對甲方發送回來的數據進行驗簽。
???????甲方只能用其私鑰解密由其公鑰加密后的任何信息。 非對稱加密算法的保密性比較好,它消除了最終用戶交換密鑰的需要。
非對稱密碼體制的特點:算法強度復雜、安全性依賴于算法與密鑰但是由于其算法復雜,而使得加密解密速度沒有對稱加密解密的速度快。對稱密碼體制中只有一種密鑰,并且是非公開的,如果要解密就得讓對方知道密鑰。所以保證其安全性就是保證密鑰的安全,而非對稱密鑰體制有兩種密鑰,其中一個是公開的,這樣就可以不需要像對稱密碼那樣傳輸對方的密鑰了。這樣安全性就大了很多。
SSH協議
SSH是一種加密的網絡傳輸協議,可在不安全的網絡中為網絡服務提供安全的傳輸環境,最常見的運用是遠程登錄。SSH的交互流程是這樣的:
客戶端發送請求:這個請求其實就是ssh登錄請求,即發起者擁有服務器上的某個用戶的賬號密碼,以遠程登錄的方式來操作服務器。
服務器將公鑰發送給客戶端,這個公鑰是給客戶端進行數據加密用的
客戶端收到服務器公鑰,確定是否繼續連接?為什么會有這么一個流程呢,既然我指定了就是要連接服務器,為什么還要讓我確認一次,這會不會是多此一舉呢?其實不然,這是為了防范中間人攻擊。
客戶端用公鑰對密碼進行加密,再發送給服務器
服務器用私鑰對密碼進行解密,返回登錄結果
中間人攻擊
剛剛提到中間人攻擊,我們就來看看什么是中間人攻擊?
我們大可以想一想,在一個不安全的網絡中,如果我發送的請求被第三方截獲,而第三方把他的公鑰發給我,而我用他的公鑰對密碼進行加密,然后再發送給他,他就獲得了完整的賬號密碼,這時候他就可以拿著從我這兒竊取來的信息登錄服務器。
那么,在一個不安全的網絡中,我們該怎樣防范這種攻擊方式呢?一般有兩種方法:
服務器將公鑰公布在官方或者以其他方式公開,讓用戶可以查到進行對比,如果不匹配,就在第三步的時候取消登錄即可。
CA證書,由一個權威機構CA對公鑰進行認證,CA機構的數字簽名使得攻擊者不能偽造和篡改證書。CA機構會為申請者發放一個公鑰,CA將該公鑰和申請者的身份信息綁定在一起,并為之簽字。
如果一個用戶想鑒別另一個證書的真偽,他就用 CA 的公鑰對那個證書上的簽字進行驗證,一旦驗證通過,該證書就被認為是有效的。
SCP的傳輸
說回到SCP的傳輸,SCP的傳輸第一步就是進行SSH的登錄動作,然后再基于SSH協議進行文件的傳輸,整個傳輸過程是加密的。
在上面提到的ssh登錄流程中,是最基本的登錄流程,特點在登錄時服務器要求客戶端提供賬號密碼進行驗證,其實這樣是非常麻煩的,在每次登錄或者傳輸文件時,都要輸入賬號密碼,這對于以偷懶為終極目標的程序員來說這是不能忍受的。
SCP的免密傳輸
我們可以想一想,為什么在每次登錄的時候都需要用戶輸入密碼?
所有人都知道這是為了驗證登錄者的是否有操作權限,那換一個思路想一下,有沒有另外一種方法也能驗證登錄者有這個登錄權限呢?
當然是有的,這種驗證方式建立在非對稱加密協議上,當客戶端C想要訪問服務器S時,在客戶端生成一對密鑰(通常使用rsa協議),將客戶端C生成的公鑰放置在服務器S上,這樣在連接時只需要驗證服務器S上是否存在客戶端C的公鑰就可以完成驗證操作。(詳細流程見下文)
實現SCP免密傳輸的操作
如果你在服務器擁有一個賬號,名為downey
在某一時刻你需要用一臺客戶機A登錄到服務器上進行操作
在客戶機A的家目錄下的.ssh目錄下生成一對秘鑰,linux下的指令為:
ssh-keygen -t rsa -P “”
(ssh-keygen為秘鑰生成應用程序,-t rsa 表示加密類型為rsa)
執行上述命令后,系統會提示選擇生成秘鑰放置的目錄和密碼,一般為默認選擇,一路回車。(但是如果你要追求更高的安全性,你可以選擇添加上私鑰密碼),然后在/home/downey/.ssh目錄下就會生成兩個文件:id_rsa和id_rsa.pub,其中id_rsa為私鑰,而id_rsa.pub為公鑰。
在服務器端的/home/downey/.ssh/目錄下新建文件authorized_keys(如果有則不用創建),將客戶端A上剛剛生成的id_rsa.pub文件中的內容復制到服務器端 /home/downey/.ssh/authorized_keys文件中(如果里面有內容則另起一行)
這樣就可以直接用scp指令(或者ssh登錄)進行文件傳輸而不用進行賬號密碼驗證了,相當于客戶機(操作機器)與服務器建立了安全連接(原理見下文),如果換一臺機器登錄,依舊需要驗證(因為服務器端的公鑰只與這臺機器上私鑰相匹配)。
注意
在這些文件操作的時候,特別需要注意的就是文件的權限問題,很多朋友就是把文件從其他地方復制過來,然后修改文件確保文件內容與目標一致就可以,但是發現這樣的操作并沒有達到免密傳輸的效果,很可能就是文件權限出了問題
同時,在某些服務器平臺上,可能會提供網頁端的接口來存放客戶端的pub_key,就像github添加公鑰的操作方式,但是原理都是將客戶端公鑰添加到服務器中
免密傳輸的登錄流程
實現SCP傳輸的第一步是通信雙方進行安全連接(登錄),上面提到的SSH登錄流程為SSH首次登錄的大概講解,我們不妨來詳細探究在免密傳輸時的登錄流程:
客戶端向服務端發送連接請求,詢問服務器是否支持pubkey的方式進行登錄
服務端收到客戶端的請求,表示接收pubkey的方式進行登錄。
接收到服務端的回復,客戶端決定使用pubkey的方式進行登錄,客戶端將一段數據用私鑰進行加密,生成簽名,并且將自己的公鑰發送給服務器。
服務端收到客戶端發過來的數據,首先將客戶端的公鑰取出來,在/home/$USER/.ssh/authorized_keys/中查找是否存在客戶端的公鑰,如果有,進行對比。
僅僅對比是否存在客戶端的公鑰當然是不夠安全的,服務器接著使用客戶端提供的公鑰對客戶端發過來的簽名(經私鑰加密)進行解密,如果解密后的數據內容正確,表示整個驗證流程完成。
服務端返回登錄結果。
SSH登錄流程疑難解答
客戶端發送給服務器的簽名數據
在上述免密傳輸的登錄部分的第三點我有提到,客戶端將一段數據用私鑰加密生成簽名,然后服務器再對這段數據進行解密,那么服務器怎么知道這段數據是否正確呢?
首先,客戶端發送給服務器的數據字段是這樣的:
byte SSH_MSG_USERAUTH_REQUEST string user name string service name string "publickey" boolean TRUE string public key algorithm name string public key to be used for authentication string signature //數據簽名部分而客戶端使用私鑰進行加密的數據字段是這樣的:
string session identifier byte SSH_MSG_USERAUTH_REQUEST string user name string service name string "publickey" boolean TRUE string public key algorithm name string public key to be used for authentication對比發現,事實上客戶端同時發了一份數據和數據的簽名給服務端,服務端就可以做對比了。
為什么公鑰可以對私鑰加密的數據解密
很多朋友看完上述免密傳輸登錄流程之后,表示非常疑惑:
為什么公鑰可以對私鑰加密的數據進行解密?
公鑰本來就是公開的,那豈不是私鑰加密的數據根本沒有安全性可言?
首先回答第一個問題:為什么公鑰可以對私鑰的加密數據進行解密。答案是:這是SSH協議的規定(好像是廢話)。
好吧,正經地回答第二個問題,公鑰是公開的,所有人都可以獲得,而私鑰只有擁有者才有,那由這對密鑰加密的數據是否就沒有安全性可言呢?
答案當然不是,安全性高著呢。只是,一般的加密過程是公鑰加密,私鑰解密,這部分數據自然是安全的。
那么私鑰加密的數據呢,私鑰加密的數據確實沒有安全性可言,因為用私鑰加密數據根本就不是為了安全性,而是作為一種驗證身份的手段。
因為私鑰是唯一的,一旦使用公鑰對私鑰加密的數據解密成功,服務端S就可以完全確定這條消息是由擁有對應私鑰的客戶端C發出的,而不是第三方偽裝者發出的。
所以,公鑰加密私鑰解密,是為了數據的安全性,而私鑰加密公鑰解密,則是為了驗證數據發送者的身份。
數據傳輸的加密方式
一般情況下SSH使用rsa加密算法登錄,SCP基于SSH協議,所以很多人自然地認為在數據傳輸時,使用的加密算法也是rsa。
事實上,由于非對稱加密算法計算太過于耗時,對所有數據進行加密根本不現實,所以在傳輸數據時一般使用對稱加密算法。
上面有提到,對稱加密算法的弊端是密鑰傳輸過程容易被竊取,所以通常使用非對稱加密算法來傳輸對稱加密算法的密鑰,來保證安全性。
為此,我還使用wareshark工具試圖梳理整個數據傳輸流程,花了一天的時間得出一個結論:針對整個SCP實現的加密算法這一塊,以博主的水平,暫時惹不起…(不過也只是暫時!!)
不過收獲還是有的:SCP數據傳輸流程結合了多種加密算法,同時還根據不同級別的安全要求結合不同的加密算法。
一般來說,綜合對稱和非對稱加密算法的特性,非對稱加密一般用于登錄驗證、密鑰傳輸等數據量小、安全性要求較高的的部分。
而對稱算法用來傳輸大量數據。
網上的錯誤描述
事實上,網絡上對于SSH的登錄過程描述有不少錯誤之處,最經典的一個錯誤觀點是服務器發送一個通過公鑰加密的字符串給客戶端,客戶端私鑰進行解密,然后發給服務端。
服務端將發出的字符串與收到的字符串進行對于,完成驗證過程。
這種做法看起來是非常合理的,但事實上SSH并不采用這種做法,具體原因引用官方文檔中的一句話:
the signing operation involves some expensive computation.
To avoid unnecessary processing and user interaction。
這句話意思很簡單,加密的計算操作是非常耗時的,我們應該避免不必要的交互以節省資源。
為什么我那么自信確定它們的描述有誤呢?并不是飄柔給我的自信,而是官方文檔
(多嘴一句,找資源一定要先找官方文檔的)
github的免密傳輸
用過github的盆友可能對免密傳輸有種熟悉的感覺,沒錯!在github的配置中,如果需要進行免密傳輸,流程是:
在客戶機生成一對秘鑰,同樣是id_rsa,id_rsa.pub
將id_rsa.pub里的內容添加到github的settings的SSH and GPG keys選項頁面中
同樣的,相當于github服務端與機器已經建立用戶識別機制,不需要再用賬號密碼來識別。
好了,關于SCP傳輸的討論就到此為止啦,如果朋友們對于這個有什么疑問或者發現有文章中有什么錯誤,歡迎留言
原創博客,轉載請注明出處!
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Linux scp 免密码 传输文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 写最少的代码,避免给自己找麻烦
- 下一篇: 计算机触摸板设置方法,解决办法:四种关闭