日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

几种方法来实现scp拷贝时无需输入密码

發布時間:2025/3/21 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 几种方法来实现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之外的人即使竊取了數據也無法解密得到原始的數據?基于公鑰和私鑰的加密可以完成這個需求,具體流程如下:

  • Bob將他的公鑰發送給Alice
  • Alice用Bob的公鑰加密需要傳輸的數據然后發送給Bob
  • Bob用他的私鑰解密Alice的消息
  • 基于公鑰和私鑰的認證過程

    還是Alice和Bob,Alice想把一段數據發送給Bob(注意這里并不強調數據的安全性),當Bob收到數據時如何判斷該數據確實是Alic發送的且傳輸過程中沒有被篡改?基于公鑰和私鑰的認證可以完成這個需求,具體流程如下:

  • Alice用她的私鑰對數據加密(或者對于數據的哈希值進行加密作為簽名)
  • Alice將加密后的數據(或者明文數據+簽名)發送給Bob
  • Bob用Alice的公鑰解密數據(或校驗簽名),如果解密(校驗)成功則可以保證數據的發送方肯定是Alice
  • 基于公鑰和私鑰的信任關系

    了解了公鑰/私鑰以及加密/認證這些概念后,我們就可以在scp中使用公鑰/私鑰來建立一個信任關系,從而在數據傳輸時完成自動認證而無需輸入密碼。

  • User在A主機將SCP請求使用自己的私鑰進行加密,然后傳輸給B主機
  • B主機在收到SCP請求時,使用User的公鑰進行解密
  • 如果解密成功,則表示該請求確實是User發送的請求,則允許操作;如果解密失敗,則表示該請求無效,直接丟棄
  • 所以這里的需要做的就是:

    • 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
  • nfer@nfer-VirtualBox:~$?ssh-keygen?-t?rsa??
  • Generating?public/private?rsa?key?pair.??
  • Enter?file?in?which?to?save?the?key?(/home/nfer/.ssh/id_rsa):???
  • Created?directory?'/home/nfer/.ssh'.??
  • Enter?passphrase?(empty?for?no?passphrase):???
  • Enter?same?passphrase?again:???
  • Your?identification?has?been?saved?in?/home/nfer/.ssh/id_rsa.??
  • Your?public?key?has?been?saved?in?/home/nfer/.ssh/id_rsa.pub.??
  • The?key?fingerprint?is:??
  • 16:77:45:71:31:7c:67:4f:91:09:07:74:4d:30:83:48?nfer@nfer-VirtualBox??
  • The?key's?randomart?image?is:??
  • +--[?RSA?2048]----+??
  • |?????????.E..*@XO|??
  • |??????????.?..oBB|??
  • |????????.?.?.??o+|??
  • |?????????o?.????.|??
  • |????????S????????|??
  • |???????.?????????|??
  • |?????????????????|??
  • |?????????????????|??
  • |?????????????????|??
  • +-----------------+??
  • nfer@nfer-VirtualBox:~$??
  • 注意上面有三處需要輸入信息,分別是:
  • 存儲公私鑰的文件夾位置,如果不輸入,則默認為~/.ssh/,文件名則默認是id_rsa和id_rsa.pub
  • 使用該公私鑰時是否需要密碼,如果不輸入則表示不需要密碼
  • 再次確認是否需要密碼
  • 將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?-p?nferzhuang?scp?a.txt?nferzhuang@192.168.1.101:/home/nferzhuang/a.txt??
  • 使用sshpass的好處就是方便直接,無需了解公私鑰、加密認證等相關知識,簡單易懂;但是使用sshpass最大的壞處就是再使用時會涉及到明文密碼,大大降低了安全性。

    方法三:使用expect腳本來自動輸入密碼

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

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

    [plain] view plain copy
  • #!/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下執行時需要按以下的規范來輸入命令:

    [plain] view plain copy
  • ./expect_scp?192.168.75.130?root?123456?/root/src_file?/root/dest_file??
  • 以上的命令執行后,將把本地/root目錄下的src_file文件拷貝到用戶名為root,密碼為123456的主機192.168.75.130中的/root下,同時還將這個源文件重命名為dest_file。

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

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

    注:關于expect部分詳細請參考《shell結合expect寫的批量scp腳本工具》

    總結

    在本文中提供了三種方法來實現scp的時候無需輸入密碼的需求,從安全性和速度上考慮建立信任關系都是最佳的方法,至于在具體的環境中選擇什么則由你自己來決定。

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的几种方法来实现scp拷贝时无需输入密码的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。