Python3之paramiko模塊


轉載☞:https://www.cnblogs.com/meng-wei-zhi/p/8258674.html

參考☞:https://www.cnblogs.com/python-nameless/p/6855804.html

Python3之paramiko模塊

一. 簡介

  paramiko是一個基於SSH用於連接遠程服務器並執行相關操作(SSHClient和SFTPClinet,即一個是遠程連接,一個是上傳下載服務),使用該模塊可以對遠程服務器進行命令或文件操作,值得一說的是,fabric和ansible內部的遠程管理就是使用的paramiko來現實。

二. 使用

1. 下載安裝

pycrypto,由於 paramiko 模塊內部依賴pycrypto,所以先下載安裝pycrypto
pip3 install pycrypto
pip3 install paramiko

2. 模塊使用

SSHClient:

遠程連接分為兩種:(1)基於用戶名密碼連接 (2)基於公鑰秘鑰連接

通過是用paramiko遠程操作,其實本質也分為兩種:(1)只用SSHClient (2)自己創建一個transport

 

(1)基於用戶名和密碼的連接

 1 import paramiko
 2  
 3 # 創建SSH對象
 4 ssh = paramiko.SSHClient()
 5 # 允許連接不在know_hosts文件中的主機
 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 7 # 連接服務器
 8 ssh.connect(hostname='c1.salt.com', port=22, username='GSuser', password='123')
 9 # 執行命令
10 stdin, stdout, stderr = ssh.exec_command('ls')
11 # 獲取命令結果
12 result = stdout.read()
13 # 關閉連接
14 ssh.close()

  SSHClient 封裝 Transport

 1 import paramiko
 2  
 3 transport = paramiko.Transport(('hostname', 22))
 4 transport.connect(username='GSuser', password='123')
 5  
 6 ssh = paramiko.SSHClient()
 7 ssh._transport = transport
 8  
 9 stdin, stdout, stderr = ssh.exec_command('df')
10 print(stdout.read())
11  
12 transport.close()

  (2)基於公鑰秘鑰連接

 1 import paramiko
 2  
 3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
 4 # 創建SSH對象
 5 ssh = paramiko.SSHClient()
 6 # 允許連接不在know_hosts文件中的主機
 7 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 8 # 連接服務器
 9 ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', key=private_key)
10 # 執行命令
11 stdin, stdout, stderr = ssh.exec_command('df')
12 # 獲取命令結果
13 result = stdout.read()
14 # 關閉連接
15 ssh.close()

  SSHClient 封裝Transport

1 import paramiko
2  
3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
4 transport = paramiko.Transport(('hostname', 22))
5 transport.connect(username='wupeiqi', pkey=private_key)
6 ssh = paramiko.SSHClient()
7 ssh._transport = transport
8 stdin, stdout, stderr = ssh.exec_command('df')
9 transport.close()

 

SFTPClient:

  用於連接遠程服務器並進行上傳下載功能。

(1)基於用戶名密碼上傳下載

 1 import paramiko
 2  
 3 transport = paramiko.Transport(('hostname',22))
 4 transport.connect(username='GSuser',password='123')
 5  
 6 sftp = paramiko.SFTPClient.from_transport(transport)
 7 # 將location.py 上傳至服務器 /tmp/test.py
 8 sftp.put('/tmp/location.py', '/tmp/test.py')
 9 # 將remove_path 下載到本地 local_path
10 sftp.get('remove_path', 'local_path')
11  
12 transport.close()

(2)基於公鑰秘鑰上傳下載

 1 import paramiko
 2  
 3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
 4  
 5 transport = paramiko.Transport(('hostname', 22))
 6 transport.connect(username='GSuser', pkey=private_key )
 7  
 8 sftp = paramiko.SFTPClient.from_transport(transport)
 9 # 將location.py 上傳至服務器 /tmp/test.py
10 sftp.put('/tmp/location.py', '/tmp/test.py')
11 # 將remove_path 下載到本地 local_path
12 sftp.get('remove_path', 'local_path')
13  
14 transport.close()

  Demo: 實現遠程命令執行和文件上傳

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 import paramiko
 4  
 5 class SSHConnection(object):
 6  
 7     def __init__(self, host='192.168.12.68', port=22, username='locojoy',pwd='123321QQ!'):
 8         self.host = host
 9         self.port = port
10         self.username = username
11         self.pwd = pwd
12         self.__k = None
13  
14     def run(self):
15         self.connect()  # 連接遠程服務器
16         self.upload('db.py','/tmp/1.py')  # 將本地的db.py文件上傳到遠端服務器的/tmp/目錄下並改名為1.py
17         self.cmd('df')  # 執行df 命令
18         self.close()    # 關閉連接
19  
20     def connect(self):
21         transport = paramiko.Transport((self.host, self.port))
22         transport.connect(username=self.username, password=self.pwd)
23         self.__transport = transport
24  
25     def close(self):
26         self.__transport.close()
27  
28     def upload(self,local_path,target_path):
29         sftp = paramiko.SFTPClient.from_transport(self.__transport)
30         sftp.put(local_path,target_path)
31  
32     def cmd(self, command):
33         ssh = paramiko.SSHClient()
34         ssh._transport = self.__transport
35         # 執行命令
36         stdin, stdout, stderr = ssh.exec_command(command)
37         # 獲取命令結果
38         result = stdout.read()
39         print(result)
40         return result
41  
42 obj = SSHConnection()
43 obj.run()

  paramiko在堡壘機中的應用

(1)簡單實例:遠程連接一台主機,操作命令,linux版本,輸入終端為回車則發送命令。不支持tab補全功能。

 1 import paramiko, sys, os, socket, select, getpass
 2 from paramiko.py3compat import u   # 在python3中是這樣使用的,如果在Python2中則注釋這行
 3  
 4 # 這個程序依賴於終端,只能在Liunx下運行,windows用其他的方式
 5  
 6 tran = paramiko.Transport(('192.168.12.68', 22,))
 7 tran.start_client()
 8 tran.auth_password('locojoy', '123321QQ!')
 9  
10 # 打開一個通道
11 chan = tran.open_session()
12 # 獲取一個終端
13 chan.get_pty()
14 # 激活器
15 chan.invoke_shell()
16  
17 # 原始的方法利用終端進行收發消息
18 # 利用sys.stdin,肆意妄為執行操作
19 # 用戶在終端輸入內容,並將內容發送至遠程服務器
20 # 遠程服務器執行命令,並將結果返回
21 # 用戶終端顯示內容
22  
23 while True:
24     # 監視用戶輸入和服務器返回數據
25     # sys.stdin 處理用戶輸入
26     # chan 是之前創建的通道,用於接收服務器返回信息
27     # 通過select監聽終端(輸入輸出),一旦變化,就將拿到的數據發送給服務器
28     # 通過監聽socket句柄,如果有變化表示服務器要給我發消息
29     readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
30     # 通過select.select 監聽chan(打開的通道(和遠程服務器連接的狀態)), sys.stdin(輸入),一旦變化就寫入readable
31     # 當chan變化時,加入到readable,遠程服務器發送內容過來
32     if chan in readable:
33         try:
34             x = u(chan.recv(1024))  # Python3用這個
35             # x = chan.recv(1024)  Python2使用這個
36             if len(x) == 0:
37                 print('\r\n*** EOF\r\n')
38                 break
39             sys.stdout.write(x)   # 寫入緩沖區
40             sys.stdout.flush()    # 刷新,將緩沖區內容顯示出來
41         except socket.timeout:
42             pass
43     # 當sys.stdin 放入readable中時,將獲取到的內容發送到遠程服務器
44     if sys.stdin in readable:
45         inp = sys.stdin.readline()
46         chan.sendall(inp)
47  
48 chan.close()
49 tran.close()

(2)每按一個鍵就發送記錄,並支持tab自動補全

 1 import paramiko, sys, os, socket, select, getpass, termios, tty
 2 from paramiko.py3compat import u
 3  
 4 tran = paramiko.Transport(('10.211.55.4', 22,))
 5 tran.start_client()
 6 tran.auth_password('wupeiqi', '123')
 7 # 打開一個通道
 8 chan = tran.open_session()
 9 # 獲取一個終端
10 chan.get_pty()
11 # 激活器
12 chan.invoke_shell()
13  
14 # 獲取原tty屬性
15 oldtty = termios.tcgetattr(sys.stdin)
16 try:
17     # 為tty設置新屬性
18     # 默認當前tty設備屬性:
19     #   輸入一行回車,執行
20     #   CTRL+C 進程退出,遇到特殊字符,特殊處理。
21     # 這是為原始模式,不認識所有特殊符號
22     # 放置特殊字符應用在當前終端,如此設置,將所有的用戶輸入均發送到遠程服務器
23     tty.setraw(sys.stdin.fileno())  # 恢復終端原始狀態,每按一個鍵就發送
24     chan.settimeout(0.0)
25  
26     while True:
27         # 監視 用戶輸入 和 遠程服務器返回數據(socket)
28         # 阻塞,直到句柄可讀
29         r, w, e = select.select([chan, sys.stdin], [], [], 1)
30         if chan in r:  # 獲取服務返回的內容
31             try:
32                 x = u(chan.recv(1024))
33                 if len(x) == 0:
34                     print('\r\n*** EOF\r\n')
35                     break
36                 sys.stdout.write(x)
37                 sys.stdout.flush()
38             except socket.timeout:
39                 pass
40         if sys.stdin in r: # 發送命令
41             x = sys.stdin.read(1) # 讀取一個字符
42             if len(x) == 0:
43                 break
44             chan.send(x) # 發送一個字符
45  
46 finally:
47     # 重新設置終端屬性,將終端狀態還原
48     termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
49  
50 chan.close()
51 tran.close()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM