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)基于用戶名和密碼的連接
import paramiko
# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='c1.salt.com', port=22, username='GSuser', password='123')
# 執行命令
stdin, stdout, stderr = ssh.exec_command('ls')
# 獲取命令結果
result = stdout.read()
# 關閉連接
ssh.close()
SSHClient 封裝 Transport
import paramiko
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='GSuser', password='123')
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
print(stdout.read())
transport.close()
?。?)基于公鑰秘鑰連接
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', key=private_key)
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
# 關閉連接
ssh.close()
SSHClient 封裝Transport
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', pkey=private_key)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
transport.close()
?
SFTPClient:
用于連接遠程服務器并進行上傳下載功能。
(1)基于用戶名密碼上傳下載
import paramiko
transport = paramiko.Transport(('hostname',22))
transport.connect(username='GSuser',password='123')
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
transport.close()
(2)基于公鑰秘鑰上傳下載
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='GSuser', pkey=private_key )
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/location.py', '/tmp/test.py')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
transport.close()
Demo: 實現遠程命令執行和文件上傳
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
class SSHConnection(object):
def __init__(self, host='192.168.12.68', port=22, username='locojoy',pwd='123321QQ!'):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.__k = None
def run(self):
self.connect() # 連接遠程服務器
self.upload('db.py','/tmp/1.py') # 將本地的db.py文件上傳到遠端服務器的/tmp/目錄下并改名為1.py
self.cmd('df') # 執行df 命令
self.close() # 關閉連接
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 upload(self,local_path,target_path):
sftp = paramiko.SFTPClient.from_transport(self.__transport)
sftp.put(local_path,target_path)
def cmd(self, command):
ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 執行命令
stdin, stdout, stderr = ssh.exec_command(command)
# 獲取命令結果
result = stdout.read()
print(result)
return result
obj = SSHConnection()
obj.run()
paramiko在堡壘機中的應用
(1)簡單實例:遠程連接一臺主機,操作命令,linux版本,輸入終端為回車則發送命令。不支持tab補全功能。
import paramiko, sys, os, socket, select, getpass
from paramiko.py3compat import u # 在python3中是這樣使用的,如果在Python2中則注釋這行
# 這個程序依賴于終端,只能在Liunx下運行,windows用其他的方式
tran = paramiko.Transport(('192.168.12.68', 22,))
tran.start_client()
tran.auth_password('locojoy', '123321QQ!')
# 打開一個通道
chan = tran.open_session()
# 獲取一個終端
chan.get_pty()
# 激活器
chan.invoke_shell()
# 原始的方法利用終端進行收發消息
# 利用sys.stdin,肆意妄為執行操作
# 用戶在終端輸入內容,并將內容發送至遠程服務器
# 遠程服務器執行命令,并將結果返回
# 用戶終端顯示內容
while True:
# 監視用戶輸入和服務器返回數據
# sys.stdin 處理用戶輸入
# chan 是之前創建的通道,用于接收服務器返回信息
# 通過select監聽終端(輸入輸出),一旦變化,就將拿到的數據發送給服務器
# 通過監聽socket句柄,如果有變化表示服務器要給我發消息
readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
# 通過select.select 監聽chan(打開的通道(和遠程服務器連接的狀態)), sys.stdin(輸入),一旦變化就寫入readable
# 當chan變化時,加入到readable,遠程服務器發送內容過來
if chan in readable:
try:
x = u(chan.recv(1024)) # Python3用這個
# x = chan.recv(1024) Python2使用這個
if len(x) == 0:
print('\r\n*** EOF\r\n')
break
sys.stdout.write(x) # 寫入緩沖區
sys.stdout.flush() # 刷新,將緩沖區內容顯示出來
except socket.timeout:
pass
# 當sys.stdin 放入readable中時,將獲取到的內容發送到遠程服務器
if sys.stdin in readable:
inp = sys.stdin.readline()
chan.sendall(inp)
chan.close()
tran.close()
(2)每按一個鍵就發送記錄,并支持tab自動補全
import paramiko, sys, os, socket, select, getpass, termios, tty
from paramiko.py3compat import u
tran = paramiko.Transport(('10.211.55.4', 22,))
tran.start_client()
tran.auth_password('wupeiqi', '123')
# 打開一個通道
chan = tran.open_session()
# 獲取一個終端
chan.get_pty()
# 激活器
chan.invoke_shell()
# 獲取原tty屬性
oldtty = termios.tcgetattr(sys.stdin)
try:
# 為tty設置新屬性
# 默認當前tty設備屬性:
# 輸入一行回車,執行
# CTRL+C 進程退出,遇到特殊字符,特殊處理。
# 這是為原始模式,不認識所有特殊符號
# 放置特殊字符應用在當前終端,如此設置,將所有的用戶輸入均發送到遠程服務器
tty.setraw(sys.stdin.fileno()) # 恢復終端原始狀態,每按一個鍵就發送
chan.settimeout(0.0)
while True:
# 監視 用戶輸入 和 遠程服務器返回數據(socket)
# 阻塞,直到句柄可讀
r, w, e = select.select([chan, sys.stdin], [], [], 1)
if chan in r: # 獲取服務返回的內容
try:
x = u(chan.recv(1024))
if len(x) == 0:
print('\r\n*** EOF\r\n')
break
sys.stdout.write(x)
sys.stdout.flush()
except socket.timeout:
pass
if sys.stdin in r: # 發送命令
x = sys.stdin.read(1) # 讀取一個字符
if len(x) == 0:
break
chan.send(x) # 發送一個字符
finally:
# 重新設置終端屬性,將終端狀態還原
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
chan.close()
tran.close()
?
?
?
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
