標籤:run 執行個體 檔案 利用 and 私人 dict 基礎上 obj
簡介
ssh是一個協議,OpenSSH是其中一個開源實現,paramiko是Python的一個庫,實現了SSHv2協議(底層使用cryptography)。
有了Paramiko以後,我們就可以在Python代碼中直接使用SSH協議對遠程伺服器執行操作,而不是通過ssh命令對遠程伺服器進行操作。
由於paramiko屬於第三方庫,所以需要使用如下命令先行安裝
pip3 install paramiko
Paramiko介紹
paramiko包含兩個核心組件:SSHClient和SFTPClient。
- SSHClient的作用類似於Linux的ssh命令,是對SSH會話的封裝,該類封裝了傳輸(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用於執行遠程命令。
- SFTPClient的作用類似與Linux的sftp命令,是對SFTP用戶端的封裝,用以實現遠程檔案操作,如檔案上傳、下載、修改檔案許可權等操作。
# Paramiko中的幾個基礎名詞:1、Channel:是一種類Socket,一種安全的SSH傳輸通道;2、Transport:是一種加密的會話,使用時會同步建立了一個加密的Tunnels(通道),這個Tunnels叫做Channel;3、Session:是client與Server保持串連的對象,用connect()/start_client()/start_server()開始會話。
Paramiko的基本使用SSHClient常用的方法介紹
connect():實現遠程伺服器的串連與認證,對於該方法只有hostname是必傳參數。
常用參數hostname 串連的目標主機port=SSH_PORT 指定連接埠username=None 驗證的使用者名稱password=None 驗證的使用者密碼pkey=None 私密金鑰方式用於身分識別驗證key_filename=None 一個檔案名稱或檔案清單,指定私密金鑰檔案timeout=None 可選的tcp連線逾時時間allow_agent=True, 是否允許串連到ssh代理,預設為True 允許look_for_keys=True 是否在~/.ssh中搜尋私密金鑰檔案,預設為True 允許compress=False, 是否開啟壓縮
set_missing_host_key_policy():設定遠程伺服器沒有在know_hosts檔案中記錄時的應對策略。目前支援三種策略:
設定串連的遠程主機沒有本地主機密鑰或HostKeys對象時的策略,目前支援三種:AutoAddPolicy 自動添加主機名稱及主機密鑰到本地HostKeys對象,不依賴load_system_host_key的配置。即建立立ssh串連時不需要再輸入yes或no進行確認WarningPolicy 用於記錄一個未知的主機密鑰的python警告。並接受,功能上和AutoAddPolicy類似,但是會提示是新串連RejectPolicy 自動拒絕未知的主機名稱和密鑰,依賴load_system_host_key的配置。此為預設選項
exec_command():在遠程伺服器執行Linux命令的方法。
open_sftp():在當前ssh會話的基礎上建立一個sftp會話。該方法會返回一個SFTPClient對象。
# 利用SSHClient對象的open_sftp()方法,可以直接返回一個基於當前串連的sftp對象,可以進行檔案的上傳等操作.sftp = client.open_sftp()sftp.put(‘test.txt‘,‘text.txt‘)
SSHClient常用的方法舉例
import paramiko # 執行個體化SSHClient client = paramiko.SSHClient() # 自動添加策略,儲存伺服器的主機名稱和密鑰資訊,如果不添加,那麼不再本地know_hosts檔案中記錄的主機將無法串連 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 串連SSH服務端,以使用者名稱和密碼進行認證 client.connect(hostname=‘192.168.1.105‘, port=22, username=‘root‘, password=‘123456‘) # 開啟一個Channel並執行命令 stdin, stdout, stderr = client.exec_command(‘df -h ‘) # stdout 為正確輸出,stderr為錯誤輸出,同時是有1個變數有值 # 列印執行結果 print(stdout.read().decode(‘utf-8‘)) # 關閉SSHClient client.close()
密鑰串連方式
# 配置私人密鑰檔案位置private = paramiko.RSAKey.from_private_key_file(‘/Users/ch/.ssh/id_rsa‘)#執行個體化SSHClientclient = paramiko.SSHClient()#自動添加策略,儲存伺服器的主機名稱和密鑰資訊,如果不添加,那麼不再本地know_hosts檔案中記錄的主機將無法串連client.set_missing_host_key_policy(paramiko.AutoAddPolicy())#串連SSH服務端,以使用者名稱和密碼進行認證client.connect(hostname=‘10.0.0.1‘,port=22,username=‘root‘,pkey=private)
SSHClient 封裝 Transport
import paramiko # 建立一個通道 transport = paramiko.Transport((‘hostname‘, 22)) transport.connect(username=‘root‘, password=‘123‘) ssh = paramiko.SSHClient() ssh._transport = transport stdin, stdout, stderr = ssh.exec_command(‘df -h‘) print(stdout.read().decode(‘utf-8‘)) transport.close()
SFTPClient常用方法介紹
SFTPCLient作為一個sftp的用戶端對象,根據ssh傳輸協議的sftp會話,實現遠程檔案操作,如上傳、下載、許可權、狀態from_transport(cls,t) 建立一個已連通的SFTP用戶端通道put(localpath, remotepath, callback=None, confirm=True) 將本地檔案上傳到伺服器 參數confirm:是否調用stat()方法檢查檔案狀態,返回ls -l的結果get(remotepath, localpath, callback=None) 從伺服器下載檔案到本地mkdir() 在伺服器上建立目錄remove() 在伺服器上刪除目錄rename() 在伺服器上重新命名目錄stat() 查看伺服器檔案狀態listdir() 列出伺服器目錄下的檔案
SFTPClient常用方法舉例
import paramiko # 擷取Transport執行個體 tran = paramiko.Transport((‘10.0.0.3‘, 22)) # 串連SSH服務端,使用password tran.connect(username="root", password=‘123456‘) # 或使用 # 配置私人密鑰檔案位置 private = paramiko.RSAKey.from_private_key_file(‘/Users/root/.ssh/id_rsa‘) # 串連SSH服務端,使用pkey指定私密金鑰 tran.connect(username="root", pkey=private) # 擷取SFTP執行個體 sftp = paramiko.SFTPClient.from_transport(tran) # 設定上傳的本地/遠程檔案路徑 localpath = "/Users/root/Downloads/1.txt" remotepath = "/tmp/1.txt" # 執行上傳動作 sftp.put(localpath, remotepath) # 執行下載動作 sftp.get(remotepath, localpath) tran.close()
Paramiko的綜合使用例子
class SSHConnection(object): def __init__(self, host_dict): self.host = host_dict[‘host‘] self.port = host_dict[‘port‘] self.username = host_dict[‘username‘] self.pwd = host_dict[‘pwd‘] self.__k = None def connect(self): transport = paramiko.Transport((self.host,self.port)) transport.connect(username=self.username,password=self.pwd) self.__transport = transport def close(self): self.__transport.close() def run_cmd(self, command): """ 執行shell命令,返回字典 return {‘color‘: ‘red‘,‘res‘:error}或 return {‘color‘: ‘green‘, ‘res‘:res} :param command: :return: """ ssh = paramiko.SSHClient() ssh._transport = self.__transport # 執行命令 stdin, stdout, stderr = ssh.exec_command(command) # 擷取命令結果 res = unicode_utils.to_str(stdout.read()) # 擷取錯誤資訊 error = unicode_utils.to_str(stderr.read()) # 如果有錯誤資訊,返回error # 否則返回res if error.strip(): return {‘color‘:‘red‘,‘res‘:error} else: return {‘color‘: ‘green‘, ‘res‘:res} def upload(self,local_path, target_path): # 串連,上傳 sftp = paramiko.SFTPClient.from_transport(self.__transport) # 將location.py 上傳至伺服器 /tmp/test.py sftp.put(local_path, target_path, confirm=True) # print(os.stat(local_path).st_mode) # 增加許可權 # sftp.chmod(target_path, os.stat(local_path).st_mode) sftp.chmod(target_path, 0o755) # 注意這裡的許可權是八進位的,八進位需要使用0o作為首碼 def download(self,target_path, local_path): # 串連,下載 sftp = paramiko.SFTPClient.from_transport(self.__transport) # 將location.py 下載至伺服器 /tmp/test.py sftp.get(target_path, local_path) # 銷毀 def __del__(self): self.close() #unicode_utils.pydef to_str(bytes_or_str): """ 把byte類型轉換為str :param bytes_or_str: :return: """ if isinstance(bytes_or_str, bytes): value = bytes_or_str.decode(‘utf-8‘) else: value = bytes_or_str return value
參考資料
武沛齊:http://www.cnblogs.com/wupeiqi/p/5699254.html
AlexBastion Host:http://www.cnblogs.com/alex3714/articles/5286889.html
http://www.cnblogs.com/dachenzi/articles/7954443.html
Python模組學習 - Paramiko