paramikohtml
paramiko是ssh服務最常常使用的模塊,遵循SSH2協議,支持以加密和認證的方式,進行遠程服務器的鏈接。python
paramiko實現ssh2不外乎兩個角度:SSH客戶端與服務端shell
具體請參考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])
參數詳解:
詳細模塊用法見: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