4.python 系統批量運維管理器之paramiko模塊

 

 

paramikohtml

paramiko是ssh服務最常常使用的模塊,遵循SSH2協議,支持以加密和認證的方式,進行遠程服務器的鏈接。python

paramiko實現ssh2不外乎兩個角度:SSH客戶端與服務端shell

  • SSHClient:包裝了Channel,Transport,SFTPClient。
  • Channel:是一種Socket類,一種安全的SSH傳輸通道。
  • Transport:是一種加密的會話(可是這樣一個對象的Session並未創建),而且建立了一個加密的tunnels,這個tunnels叫作Channel。
  • Session:是Client與Server保持鏈接的對象,用Connect(),start_client(),start_server()開始會話。

具體請參考paramiko的庫文檔:http://docs.paramiko.org/en/2.0/index.html安全

使用pip install paramiko安裝,失敗的話,建議使用yum安裝:yum install python-paramiko服務器

代碼實例:session

paramiko遠程密碼鏈接:運維

import paramiko  

#實例化SSHClient

client = paramiko.SSHClient()

#建立ssh鏈接日誌文件(只保留前一次鏈接的詳細日誌,之前的日誌會自動被覆蓋)
paramiko.util.log_to_file('paramiko.log')

#自動添加策略,保存服務器的主機名和密鑰信息,若是不添加,不在know_hosts文件中記錄的主機將沒法鏈接

client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

#鏈接SSH服務端,以用戶名和密碼進行認證

client.connect(hostname='127.0.0.1', port=22, username='root', password='123456')

#打開一個Channel並執行命令

stdin,stdout,stderr = client.exec_command(command)

#打印執行結果

result=stdout.read().decode('utf-8')
print(result)

#關閉SSHClient鏈接
client.close()

SSHClient()裏面有一個transport變量,這個是用於獲取鏈接的,所以咱們也能夠單獨獲取到transport變量,而後執行鏈接操做:ssh

import paramiko

#建立一個通道 transport
= paramiko.Transport(('127.0.0.1', 22))

#用戶名密碼鏈接服務器 transport.connect(username
='root', password='123456')

#實例化SSHClient ssh
= paramiko.SSHClient()
ssh._transport
= transport stdin, stdout, stderr = ssh.exec_command(command) print(stdout.read().decode('utf-8'))

#關閉鏈接 transport.close()

paramiko使用密鑰鏈接socket

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
='127.0.0.1',port=22,username='root',pkey=private)
# 打開一個Channel並執行命令 stdin, stdout, stderr
= client.exec_command(command) # stdout 爲正確輸出,stderr爲錯誤輸出,同時是有1個變量有值
# 打印執行結果 print(stdout.read().decode(
'utf-8'))
# 關閉SSHClient client.close()

使用transport封裝使用密鑰鏈接:ui

import paramiko 
# 配置私人密鑰文件位置
private = paramiko.RSAKey.from_private_key_file('/Users/zjz/.ssh/id_rsa')
# 建立一個通道 transport
= paramiko.Transport(('127.0.0.1', 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實現上傳文件

import paramiko 
# 獲取Transport實例 tran
= paramiko.Transport(('127.0.0.1', 22))
# 鏈接SSH服務端,使用password tran.connect(username
="root", password='123456')
# 或使用 # 配置私人密鑰文件位置
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/1.txt" remotepath = "/tmp/1.txt"
# 執行上傳動做 sftp.put(localpath, remotepath)
#若是遠程主機有這個文件則返回一個對象,負責拋出異常
try:
sftp.file(remotepath)
print("上傳成功")
except IOError:
print("上傳失敗")
finally:
# 關閉鏈接 tran.close()

SFTPClinet實現下載文件

import paramiko
import os
# 獲取Transport實例 tran
= paramiko.Transport(('127.0.0.1', 22))
# 鏈接SSH服務端,使用password tran.connect(username
="root", password='123456')
# 或使用 # 配置私人密鑰文件位置
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/1.txt" remotepath = "/tmp/1.txt"
#判斷遠程服務器是否有這個文件
try: sftp.file(remotepath)
#執行下載動做 sftp.
get(remotepath, localpath) except IOError as e:
print(remotepath+"remote file no exit!")
exit()
finally:
#關閉鏈接
sftp.close()
if os.path.isfile(localpath):
print("下載成功")
else:
print("下載失敗")

SSHClient也能夠實現交互式終端

核心代碼:

# 打開一個通道 channel = trans.open_session() 
# 獲取終端 channel.get_pty()
# 激活終端,這樣就能夠登陸到終端了,就和咱們用相似於xshell登陸系統同樣 channel.invoke_shell()

重要的是select模塊的使用,select會監聽socket或者文件描述符的I/O狀態變化,並返回變化的socket或者文件描述符的對象

r_list,w_list,x_list = select.select(rlist, wlist, xlist, timeout])

參數詳解:

  • rlist:list類型,監聽其中的socket或者文件描述符是否變爲可讀狀態,返回那些可讀的socket或者文件描述符組成的list
  • wlist:list類型,監聽其中的socket或者文件描述符是否變爲可寫狀態,返回那些可寫的socket或者文件描述符組成的list
  • xlist:list類型,監聽其中的socket或者文件描述符是否出錯,返回那些出錯的socket或者文件描述符組成的list
  • timeout:設置select的超時時間,設置爲None表明永遠不會超時,即阻塞。

詳細模塊用法見:https://blog.csdn.net/weixin_43367828/article/details/84640103

xshell功能實現

import paramiko 
import os
import select
import sys

# 創建一個socket

trans = paramiko.Transport(('127.0.0.1', 22))

# 啓動一個客戶端

trans.start_client()

# 若是使用rsa密鑰登陸的話
''' default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa') prikey = paramiko.RSAKey.from_private_key_file(default_key_file) trans.auth_publickey(username='super', key=prikey) '''

# 若是使用用戶名和密碼登陸
trans.auth_password(username=
'root', password='123456')

# 打開一個通道
channel = trans.open_session()

# 獲取終端
channel.get_pty()

# 激活終端,這樣就能夠登陸到終端了,就和咱們用相似於xshell登陸系統同樣
channel.invoke_shell()

# 下面就能夠執行你全部的操做,用select實現
# 對輸入終端sys.stdin和 通道進行監控,
# 當用戶在終端輸入命令後,將命令交給channel通道,這個時候sys.stdin就發生變化,select就能夠感知
# channel的發送命令、獲取結果過程其實就是一個socket的發送和接受信息的過程

while True:
readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
# 若是是用戶輸入命令了,sys.stdin發生變化
if sys.stdin in readlist:
# 獲取輸入的內容
input_cmd = sys.stdin.read(1)
# 將命令發送給服務器
channel.sendall(input_cmd)
# 服務器返回告終果,channel通道接受到結果,發生變化 select感知到
if channel in readlist:
# 獲取結果
result = channel.recv(1024)
# 斷開鏈接後退出
if len(result) == 0:
print("\r\n**** EOF **** \r\n")
break
# 輸出到屏幕
sys.stdout.write(result.decode())
sys.stdout.flush()
# 關閉通道
channel.close()
# 關閉連接
trans.close()

SSHClient實現堡壘機模式下的命令執行

         堡壘機在必定程度上提高了運營安全級別,但同時也提升了平常運營成本,做爲管理的中轉設備,任何針對業務服務器的管理請求都會通過此節點,好比SSH協議,首先運維人員在辦公電腦經過SSH協議登錄堡壘機,再經過堡壘機SSH跳轉到全部的業務服務器進行維護操做。

         能夠利用paramiko的invoke_shell機制實現經過堡壘機實現服務器操做,原理是SSHClient.connect到堡壘機後開啓一個新的SSH會話(session),經過新的會話運行 "sshuser@IP" 去實現遠程命令執行。

SFTPClient實現堡壘機模式下的遠程文件上傳

        實現堡壘機模式下的文件上傳,原理是經過paramiko的SFTPClient將文件從辦公設備上傳至堡壘機指定的臨時目錄,如 /tmp。再經過SSHClient的invoke_shell方法開啓ssh會話,執行scp命令,將 /tmp下的指定文件複製到目標業務服務器上。

具體代碼實現請參考:http://www.cnblogs.com/charliedaifu/p/10098848.html

 

sftp是安全文件傳輸協議,提供一種安全的加密方法,sftp是SSH的一部分,SFTPClient類實現了sftp客戶端,經過已創建的SSH通道傳輸文件,與其餘的操做,以下:

方法 描述
sftp.getcwd() 返回當前工做目錄
sftp.chdir(path) 改變工做目錄
sftp.chmod(path, mode) 修改權限
sftp.chown(path, uid, gid) 設置屬主屬組
sftp.close() 關閉sftp
sftp.file(filename, mode=’r’, bufsize=-1) 讀取文件
sftp.from_transport(s) 建立SFTP客戶端通道
sftp.listdir(path=’.’) 列出目錄,返回一個列表
sftp.listdir_attr(path=’.’) 列出目錄,返回一個SFTPAttributes列表
sftp.mkdir(path, mode=511) 建立目錄
sftp.normalize(path) 返回規範化path
sftp.open(filename, mode=’r’, bufsize=-1) 在遠程服務器打開文件
sftp.put(localpath, remotepath, callback=None) localpath文件上傳到遠程服務器remotepath
sftp.get(remotepath, localpath, callback=None) 從遠程服務器remotepath拉文件到本地localpath
sftp.readlink(path) 返回一個符號連接目標
sftp.remove(path) 刪除文件
sftp.rename(oldpath, newpath) 重命名文件或目錄
sftp.rmdir(path) 刪除目錄
sftp.stat(path) 返回遠程服務器文件信息(返回一個對象的屬性)
sftp.truncate(path, size) 截取文件大小
sftp.symlink(source, dest) 建立一個軟連接(快捷方式)
sftp.unlink(path) 刪除軟連接

 

參考鏈接:

https://blog.csdn.net/songfreeman/article/details/50920767

https://blog.csdn.net/qq_29778641/article/details/82186438

https://blog.csdn.net/forever_wen/article/details/82556154

相關文章
相關標籤/搜索