一、paramiko 安裝
paramiko是Python的一個第三方庫,所以我們要使用pip安裝
pip install paramiko
二、什么是paramiko
SSH是一個協議,paramiko是使用SSHv2協議(底層使用的是cryptography)的一個第三方的庫
2.1:paramiko包括兩個核心的組件
SSHClient:它的作用類似於Linux的SSH命令,是對SSH會話的一個類的封裝,這個類封裝了傳輸(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通過用於執行遠程命令。
SFTPClient:它的作用類似Linux的SFTP命令,是對SFTP客戶端的一個類的封裝。主要是實現對遠程文件的操作,上傳,下載,修改文件權限等操作。
2.2:paramiko有幾個基礎的名詞
Transport:是一種加密的會話,使用時會同步創建一個加密的Tunnels(通道),這個Tunnels叫Channel
Channel:是一種類的Socket,一種安全的SSH通道
Session:是client和server保持連接的對象。實現方式是connect ---> start_client ---> start_server 開始會話。
三、SSHClient使用
3.1:常用方法
connect()方法: 實現遠程服務器的連接認證,對於該方法自由一個hostname是必須傳的參數 常用參數: hostname:連接的目標主機 port:目標主機的端口 username:驗證的用戶可以為None password:驗證的密碼可以為None pkey:私鑰的驗證方式可以為None key_filename:一個文件名或者一個文件列表,指定私鑰文件 timeout:TCP連接的超時時間,可以為None allow_agent:是否允許連接到ssh代理,默認為True look_for_keys:是否在~/.ssh中搜索秘鑰文件,默認為True compress:是否打開壓縮,默認False set_missing_host_key_policy()方法: 設置遠程服務器沒有在know_hosts文件中記錄時的應對策略,目前支持三種策略 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對象 通過這個對象可以實現上傳下載的功能
3.2:使用密碼連接(一)
import paramiko # 實例化SSHClient client = paramiko.SSHClient() # 自動添加策略,保存服務器的主機名和密鑰信息,如果不添加,那么不再本地know_hosts文件中記錄的主機將無法連接 client.set_missing.host_key_policy(paramiko.AutoAddPolicy()) # 連接SSH服務器,用戶名密碼認證 client.connect(hostname='192.168.163.129',port=22,username='root',password='zhujingzhi') # 打開一個Chanent並執行命令 stdin,stdout,stderr = client.exec_command('df -h') # stdout 為正確輸出,stderr為錯誤輸出,同時是有1個變量有值 # 打印結果 print(stdout.read().decode('utf8')) # 關閉連接 client.close()
3.3:使用密碼連接(二)transport封裝推薦使用
import paramiko # 創建一個通道 transport = paramiko.transport(('192.168.163.129', 22)) transport.connect(username='root', password='zhujingzhi') # 實例化SSHClient client = paramiko.SSHClient() client._transport = transport # 打開一個Chanent並執行命令 stdin,stdout,stderr = client.exec_command('df -h') # stdout 為正確輸出,stderr為錯誤輸出,同時是有1個變量有值 # 打印結果 print(stdout.read().decode('utf8')) # 關閉連接 transport.close()
3.4:使用秘鑰連接(一)
import paramiko # 配置私人密鑰文件位置 private = paramiko.RSAKey.from_private_key_file('/Users/zjz/.ssh/id_rsa') #實例化SSHClient client = paramiko.SSHClient() #自動添加策略,保存服務器的主機名和密鑰信息,如果不添加,那么不再本地know_hosts文件中記錄的主機將無法連接 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #連接SSH服務端,以用戶名和密碼進行認證 client.connect(hostname='192.168.163.129',port=22,username='root',pkey=private) # 打開一個Channel並執行命令 stdin, stdout, stderr = client.exec_command('df -h ') # stdout 為正確輸出,stderr為錯誤輸出,同時是有1個變量有值 # 打印執行結果 print(stdout.read().decode('utf-8')) # 關閉SSHClient client.close()
3.5:使用秘鑰連接(二)transport封裝推薦使用
import paramiko # 配置私人密鑰文件位置 private = paramiko.RSAKey.from_private_key_file('/Users/zjz/.ssh/id_rsa') # 創建一個通道 transport = paramiko.Transport(('192.168.163.129', 22)) transport.connect(username='root', pkey=private_key) #實例化SSHClient client = paramiko.SSHClient() client._transport = transport # 打開一個Channel並執行命令 stdin, stdout, stderr = client.exec_command('df -h ') # stdout 為正確輸出,stderr為錯誤輸出,同時是有1個變量有值 # 打印執行結果 print(stdout.read().decode('utf-8')) # 關閉SSHClient transport.close()
四、SFTPClient使用
4.1:常用方法
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() 列出服務器目錄下的文件
4.2:上傳功能
import paramiko # 獲取Transport實例 tran = paramiko.Transport(('192.168.163.129', 22)) # 連接SSH服務端,使用password tran.connect(username="root", password='zhujingzhi') # 或使用 # 配置私人密鑰文件位置 private = paramiko.RSAKey.from_private_key_file('/Users/zjz/.ssh/id_rsa') # 連接SSH服務端,使用pkey指定私鑰 tran.connect(username="root", pkey=private) # 獲取SFTP實例 sftp = paramiko.SFTPClient.from_transport(tran) # 設置上傳的本地/遠程文件路徑 localpath = "/Users/zjz/Downloads/1.txt" remotepath = "/tmp/1.txt" # 執行上傳動作 sftp.put(localpath, remotepath) # 關閉連接 tran.close()
4.3:下載功能
import paramiko # 獲取Transport實例 tran = paramiko.Transport(('192.168.163.129', 22)) # 連接SSH服務端,使用password tran.connect(username="root", password='zhujingzhi') # 或使用 # 配置私人密鑰文件位置 private = paramiko.RSAKey.from_private_key_file('/Users/zjz/.ssh/id_rsa') # 連接SSH服務端,使用pkey指定私鑰 tran.connect(username="root", pkey=private) # 獲取SFTP實例 sftp = paramiko.SFTPClient.from_transport(tran) # 設置上傳的本地/遠程文件路徑 localpath = "/Users/zjz/Downloads/1.txt" remotepath = "/tmp/1.txt" # 執行下載動作 sftp.get(remotepath, localpath) # 關閉連接 tran.close()
五、綜合函數實現(復制粘貼即可使用)
5.1:transport封裝函數(推薦使用)
import paramiko class ssh(object): def __init__(self,hostdata): """ 初始化連接信息和ftp方法 :param hostdata: 連接信息字段 """ self.ip = hostdata['ip'] self.port = hostdata['port'] self.user = hostdata['user'] self.passwd = hostdata['passwd'] self.transport = paramiko.Transport((self.ip, self.port)) self.transport.connect (username=self.user, password=self.passwd) self.obj = paramiko.SSHClient() self.obj._transport = self.transport self.objsftp = self.obj.open_sftp () def run_cmd(self, cmd): """ 執行命令方法 :param cmd: 需要執行的命令 :return: """ stdin, stdout, stderr = self.obj.exec_command (cmd) return stdout.read () def run_cmdlist(self, cmdlist): """ 執行命令方法列表 :param cmdlist: 命令列表 :return: """ self.resultList = [] for cmd in cmdlist: stdin, stdout, stderr = self.obj.exec_command (cmd) self.resultList.append (stdout.read ()) return self.resultList def get(self,remotepath,localpath): """ 下載文件方法(兩個路徑都要指定文件名) :param remotepath: 服務器路徑 :param localpath: 本地路徑 :return: """ self.objsftp.get(remotepath,localpath) def put(self,localpath,remotepath): """ 上傳文件方法(兩個路徑都要指定文件名) :param localpath: 本地路徑 :param remotepath: 服務器路徑 :return: """ self.objsftp.put(localpath,remotepath) def close(self): """ 關閉方法 :return: """ self.objsftp.close () self.transport.close () # 函數的使用 if __name__ == '__main__': hostdata = { 'ip':'192.168.163.129', 'port':22, 'user':'root', 'passwd':'zhujingzhi', } host = ssh (hostdata) # 實例化遠程函數給數據庫里面的IP 端口 用戶名 密碼信息 v = host.run_cmd ('df -h') # 執行單個命令 vstr = v.decode (encoding='utf-8', errors='strict') # bytes轉字符串 v1 = host.run_cmdlist (['ls', 'df']) # 執行命令列表 print(hostdata['ip']) print(vstr) v = host.get('/root/anaconda-ks.cfg','D:\\采集\\a.cfg') # 下載文件 v = host.put('D:\\采集\\a.cfg','/opt/a.cfg') # 上傳文件 host.close()
5.1:普通方式
import paramiko class ssh(object): def __init__(self,hostdata): """ 初始化連接信息和ftp方法 :param hostdata: 連接信息字段 """ self.ip = hostdata['ip'] self.port = hostdata['port'] self.user = hostdata['user'] self.passwd = hostdata['passwd'] self.obj = paramiko.SSHClient() self.obj.set_missing_host_key_policy(paramiko.AutoAddPolicy ()) self.obj.connect (self.ip, self.port, self.user, self.passwd) self.objsftp = self.obj.open_sftp () def run_cmd(self, cmd): """ 執行命令方法 :param cmd: 需要執行的命令 :return: """ stdin, stdout, stderr = self.obj.exec_command (cmd) return stdout.read () def run_cmdlist(self, cmdlist): """ 執行命令方法列表 :param cmdlist: 命令列表 :return: """ self.resultList = [] for cmd in cmdlist: stdin, stdout, stderr = self.obj.exec_command (cmd) self.resultList.append (stdout.read ()) return self.resultList def get(self,remotepath,localpath): """ 下載文件方法(兩個路徑都要指定文件名) :param remotepath: 服務器路徑 :param localpath: 本地路徑 :return: """ self.objsftp.get(remotepath,localpath) def put(self,localpath,remotepath): """ 上傳文件方法(兩個路徑都要指定文件名) :param localpath: 本地路徑 :param remotepath: 服務器路徑 :return: """ self.objsftp.put(localpath,remotepath) def close(self): """ 關閉方法 :return: """ self.objsftp.close () self.obj.close () # 函數的使用 if __name__ == '__main__': hostdata = { 'ip':'192.168.163.129', 'port':22, 'user':'root', 'passwd':'zhujingzhi', } host = ssh (hostdata) # 實例化遠程函數給數據庫里面的IP 端口 用戶名 密碼信息 v = host.run_cmd ('df -h') # 執行單個命令 vstr = v.decode (encoding='utf-8', errors='strict') # bytes轉字符串 v1 = host.run_cmdlist (['ls', 'df']) # 執行命令列表 print(hostdata['ip']) print(vstr) v = host.get('/root/anaconda-ks.cfg','D:\\采集\\a.cfg') # 下載文件 v = host.put('D:\\采集\\a.cfg','/opt/a.cfg') # 上傳文件 host.close()