最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python使用paramiko實(shí)現(xiàn)ssh的功能詳解

 更新時(shí)間:2020年03月06日 08:53:02   作者:劉江  
這篇文章主要介紹了python使用paramiko實(shí)現(xiàn)ssh的功能詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

個(gè)人認(rèn)為python的paramiko模塊是運(yùn)維人員必學(xué)模塊之一,其ssh登錄功能是旅行居家必備工具。

安裝paramiko很簡(jiǎn)單,pip install paramiko就搞定了,其依賴(lài)庫(kù)會(huì)被一并安裝。

paramiko的官方站點(diǎn)在這里:http://www.paramiko.org/。有需要深入研究的可以閱讀官方文檔。

paramiko模塊提供了ssh及sft進(jìn)行遠(yuǎn)程登錄服務(wù)器執(zhí)行命令和上傳下載文件的功能。

一、基于用戶名和密碼的 sshclient 方式登錄

# 建立一個(gè)sshclient對(duì)象
ssh = paramiko.SSHClient()
# 允許將信任的主機(jī)自動(dòng)加入到host_allow 列表,此方法必須放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 調(diào)用connect方法連接服務(wù)器
ssh.connect(hostname='192.168.2.129', port=22, username='super', password='super')
# 執(zhí)行命令
stdin, stdout, stderr = ssh.exec_command('df -hl')
# 結(jié)果放到stdout中,如果有錯(cuò)誤將放到stderr中
print(stdout.read().decode())
# 關(guān)閉連接
ssh.close()

二、基于用戶名和密碼的 transport 方式登錄

方法1是傳統(tǒng)的連接服務(wù)器、執(zhí)行命令、關(guān)閉的一個(gè)操作,有時(shí)候需要登錄上服務(wù)器執(zhí)行多個(gè)操作,比如執(zhí)行命令、上傳/下載文件,方法1則無(wú)法實(shí)現(xiàn),可以通過(guò)如下方式來(lái)操作

# 實(shí)例化一個(gè)transport對(duì)象
trans = paramiko.Transport(('192.168.2.129', 22))
# 建立連接
trans.connect(username='super', password='super')

# 將sshclient的對(duì)象的transport指定為以上的trans
ssh = paramiko.SSHClient()
ssh._transport = trans
# 執(zhí)行命令,和傳統(tǒng)方法一樣
stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())

# 關(guān)閉連接
trans.close()

三、 基于公鑰密鑰的 SSHClient 方式登錄

# 指定本地的RSA私鑰文件,如果建立密鑰對(duì)時(shí)設(shè)置的有密碼,password為設(shè)定的密碼,如無(wú)不用指定password參數(shù)
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
# 建立連接
ssh = paramiko.SSHClient()
ssh.connect(hostname='192.168.2.129',
      port=22,
      username='super',
      pkey=pkey)
# 執(zhí)行命令
stdin, stdout, stderr = ssh.exec_command('df -hl')
# 結(jié)果放到stdout中,如果有錯(cuò)誤將放到stderr中
print(stdout.read().decode())
# 關(guān)閉連接
ssh.close()

以上需要確保被訪問(wèn)的服務(wù)器對(duì)應(yīng)用戶.ssh目錄下有authorized_keys文件,也就是將服務(wù)器上生成的公鑰文件保存為authorized_keys。并將私鑰文件作為paramiko的登陸密鑰

四、 基于密鑰的 Transport 方式登錄

# 指定本地的RSA私鑰文件,如果建立密鑰對(duì)時(shí)設(shè)置的有密碼,password為設(shè)定的密碼,如無(wú)不用指定password參數(shù)
pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')
# 建立連接
trans = paramiko.Transport(('192.168.2.129', 22))
trans.connect(username='super', pkey=pkey)

# 將sshclient的對(duì)象的transport指定為以上的trans
ssh = paramiko.SSHClient()
ssh._transport = trans

# 執(zhí)行命令,和傳統(tǒng)方法一樣
stdin, stdout, stderr = ssh.exec_command('df -hl')
print(stdout.read().decode())

# 關(guān)閉連接
trans.close()

五、傳文件 SFTP

# 實(shí)例化一個(gè)trans對(duì)象# 實(shí)例化一個(gè)transport對(duì)象
trans = paramiko.Transport(('192.168.2.129', 22))
# 建立連接
trans.connect(username='super', password='super')

# 實(shí)例化一個(gè) sftp對(duì)象,指定連接的通道
sftp = paramiko.SFTPClient.from_transport(trans)
# 發(fā)送文件
sftp.put(localpath='/tmp/11.txt', remotepath='/tmp/22.txt')
# 下載文件
# sftp.get(remotepath, localpath)
trans.close()

六、 實(shí)現(xiàn)輸入命令立馬返回結(jié)果的功能

以上操作都是基本的連接,如果我們想實(shí)現(xiàn)一個(gè)類(lèi)似xshell工具的功能,登錄以后可以輸入命令回車(chē)后就返回結(jié)果:

import paramiko
import os
import select
import sys

# 建立一個(gè)socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 啟動(dòng)一個(gè)客戶端
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='super', password='super')
# 打開(kāi)一個(gè)通道
channel = trans.open_session()
# 獲取終端
channel.get_pty()
# 激活終端,這樣就可以登錄到終端了,就和我們用類(lèi)似于xshell登錄系統(tǒng)一樣
channel.invoke_shell()
# 下面就可以執(zhí)行你所有的操作,用select實(shí)現(xiàn)
# 對(duì)輸入終端sys.stdin和 通道進(jìn)行監(jiān)控,
# 當(dāng)用戶在終端輸入命令后,將命令交給channel通道,這個(gè)時(shí)候sys.stdin就發(fā)生變化,select就可以感知
# channel的發(fā)送命令、獲取結(jié)果過(guò)程其實(shí)就是一個(gè)socket的發(fā)送和接受信息的過(guò)程
while True:
  readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
  # 如果是用戶輸入命令了,sys.stdin發(fā)生變化
  if sys.stdin in readlist:
    # 獲取輸入的內(nèi)容
    input_cmd = sys.stdin.read(1)
    # 將命令發(fā)送給服務(wù)器
    channel.sendall(input_cmd)

  # 服務(wù)器返回了結(jié)果,channel通道接受到結(jié)果,發(fā)生變化 select感知到
  if channel in readlist:
    # 獲取結(jié)果
    result = channel.recv(1024)
    # 斷開(kāi)連接后退出
    if len(result) == 0:
      print("\r\n**** EOF **** \r\n")
      break
    # 輸出到屏幕
    sys.stdout.write(result.decode())
    sys.stdout.flush()

# 關(guān)閉通道
channel.close()
# 關(guān)閉鏈接
trans.close()

注意:在windows中,sys.stdin不是一個(gè)socket或者file-like對(duì)象,而是一個(gè)PseudoOutputFile對(duì)象,不能被select處理。所以上面的腳本不能在windows中運(yùn)行,只能用于linux。

七、上例支持tab自動(dòng)補(bǔ)全

import paramiko
import os
import select
import sys
import tty
import termios

'''
實(shí)現(xiàn)一個(gè)xshell登錄系統(tǒng)的效果,登錄到系統(tǒng)就不斷輸入命令同時(shí)返回結(jié)果
支持自動(dòng)補(bǔ)全,直接調(diào)用服務(wù)器終端

'''
# 建立一個(gè)socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 啟動(dòng)一個(gè)客戶端
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='super', password='super')
# 打開(kāi)一個(gè)通道
channel = trans.open_session()
# 獲取終端
channel.get_pty()
# 激活終端,這樣就可以登錄到終端了,就和我們用類(lèi)似于xshell登錄系統(tǒng)一樣
channel.invoke_shell()

# 獲取原操作終端屬性
oldtty = termios.tcgetattr(sys.stdin)
try:
  # 將現(xiàn)在的操作終端屬性設(shè)置為服務(wù)器上的原生終端屬性,可以支持tab了
  tty.setraw(sys.stdin)
  channel.settimeout(0)

  while True:
    readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
    # 如果是用戶輸入命令了,sys.stdin發(fā)生變化
    if sys.stdin in readlist:
      # 獲取輸入的內(nèi)容,輸入一個(gè)字符發(fā)送1個(gè)字符
      input_cmd = sys.stdin.read(1)
      # 將命令發(fā)送給服務(wù)器
      channel.sendall(input_cmd)

    # 服務(wù)器返回了結(jié)果,channel通道接受到結(jié)果,發(fā)生變化 select感知到
    if channel in readlist:
      # 獲取結(jié)果
      result = channel.recv(1024)
      # 斷開(kāi)連接后退出
      if len(result) == 0:
        print("\r\n**** EOF **** \r\n")
        break
      # 輸出到屏幕
      sys.stdout.write(result.decode())
      sys.stdout.flush()
finally:
  # 執(zhí)行完后將現(xiàn)在的終端屬性恢復(fù)為原操作終端屬性
  termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

# 關(guān)閉通道
channel.close()
# 關(guān)閉鏈接
trans.close()

八、 SSH服務(wù)端的實(shí)現(xiàn)

實(shí)現(xiàn)SSH服務(wù)端必須繼承ServerInterface,并實(shí)現(xiàn)里面相應(yīng)的方法。具體代碼如下:

import socket
import sys
import threading
import paramiko

host_key = paramiko.RSAKey(filename='private_key.key')

class Server(paramiko.ServerInterface):
  def __init__(self):
  #執(zhí)行start_server()方法首先會(huì)觸發(fā)Event,如果返回成功,is_active返回True
    self.event = threading.Event()

  #當(dāng)is_active返回True,進(jìn)入到認(rèn)證階段
  def check_auth_password(self, username, password):
    if (username == 'root') and (password == '123456'):
      return paramiko.AUTH_SUCCESSFUL
    return paramiko.AUTH_FAILED

  #當(dāng)認(rèn)證成功,client會(huì)請(qǐng)求打開(kāi)一個(gè)Channel
  def check_channel_request(self, kind, chanid):
    if kind == 'session':
      return paramiko.OPEN_SUCCEEDED
#命令行接收ip與port
server = sys.argv[1]
ssh_port = int(sys.argv[2])

#建立socket
try:
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  #TCP socket
  sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  sock.bind((server, ssh_port))  
  sock.listen(100)  
  print '[+] Listening for connection ...'
  client, addr = sock.accept()
except Exception, e:
  print '[-] Listen failed: ' + str(e)
  sys.exit(1)
print '[+] Got a connection!'

try:
  #用sock.accept()返回的socket實(shí)例化Transport
  bhSession = paramiko.Transport(client)
  #添加一個(gè)RSA密鑰加密會(huì)話
  bhSession.add_server_key(host_key)
  server = Server()
  try:
  #啟動(dòng)SSH服務(wù)端
    bhSession.start_server(server=server)
  except paramiko.SSHException, x:
    print '[-] SSH negotiation failed'
  chan = bhSession.accept(20) 
  print '[+] Authenticated!'
  print chan.recv(1024)
  chan.send("Welcome to my ssh")
  while True:
    try:
      command = raw_input("Enter command:").strip("\n") 
      if command != 'exit':
        chan.send(command)
        print chan.recv(1024) + '\n'
      else:
        chan.send('exit')
        print 'exiting'
        bhSession.close()
        raise Exception('exit')
    except KeyboardInterrupt:
      bhSession.close()
except Exception, e:
  print '[-] Caught exception: ' + str(e)
  try:
    bhSession.close()
  except:
    pass
  sys.exit(1)

到此這篇關(guān)于python使用paramiko實(shí)現(xiàn)ssh的功能詳解的文章就介紹到這了,更多相關(guān)python paramiko實(shí)現(xiàn)ssh內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python fileinput模塊使用實(shí)例

    Python fileinput模塊使用實(shí)例

    這篇文章主要介紹了Python fileinput模塊使用實(shí)例,本文講解了典型用法、基本格式、默認(rèn)格式、常用函數(shù)和常見(jiàn)例子等內(nèi)容,需要的朋友可以參考下
    2015-06-06
  • Python基礎(chǔ)學(xué)習(xí)之反射機(jī)制詳解

    Python基礎(chǔ)學(xué)習(xí)之反射機(jī)制詳解

    在Python中,反射是指通過(guò)一組內(nèi)置的函數(shù)和語(yǔ)句,在運(yùn)行時(shí)動(dòng)態(tài)地訪問(wèn)、檢查和修改對(duì)象的屬性、方法和類(lèi)信息的機(jī)制。本文將通過(guò)簡(jiǎn)單的示例和大家講講Python中的反射機(jī)制,希望對(duì)大家有所幫助
    2023-03-03
  • pycharm運(yùn)行scrapy過(guò)程圖解

    pycharm運(yùn)行scrapy過(guò)程圖解

    這篇文章主要介紹了pycharm運(yùn)行scrapy過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 淺談python量化 雙均線策略(金叉死叉)

    淺談python量化 雙均線策略(金叉死叉)

    這篇文章主要介紹了淺談python量化 雙均線策略(金叉死叉),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • python的staticmethod與classmethod實(shí)現(xiàn)實(shí)例代碼

    python的staticmethod與classmethod實(shí)現(xiàn)實(shí)例代碼

    這篇文章主要介紹了python的staticmethod與classmethod實(shí)現(xiàn)實(shí)例代碼,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02
  • Python使用xpath實(shí)現(xiàn)圖片爬取

    Python使用xpath實(shí)現(xiàn)圖片爬取

    這篇文章主要介紹了Python使用xpath實(shí)現(xiàn)圖片爬取,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • python 的列表遍歷刪除實(shí)現(xiàn)代碼

    python 的列表遍歷刪除實(shí)現(xiàn)代碼

    這篇文章主要介紹了python 的列表遍歷刪除,需要的朋友可以參考下
    2015-11-11
  • Python解決ModuleNotFoundError: No module named 'PIL'的問(wèn)題

    Python解決ModuleNotFoundError: No module named&

    ModuleNotFoundError: No module named 'PIL'是一個(gè)常見(jiàn)的Python錯(cuò)誤,通常出現(xiàn)在使用Pillow庫(kù)時(shí),Pillow是Python中用于圖像處理的一個(gè)庫(kù),其前身是PIL,本文介紹了Python解決ModuleNotFoundError: No module named 'PIL'的問(wèn)題,需要的朋友可以參考下
    2024-09-09
  • Python數(shù)據(jù)結(jié)構(gòu)與算法之字典樹(shù)實(shí)現(xiàn)方法示例

    Python數(shù)據(jù)結(jié)構(gòu)與算法之字典樹(shù)實(shí)現(xiàn)方法示例

    這篇文章主要介紹了Python數(shù)據(jù)結(jié)構(gòu)與算法之字典樹(shù)實(shí)現(xiàn)方法,可實(shí)現(xiàn)針對(duì)單詞出現(xiàn)次數(shù)的統(tǒng)計(jì)功能,涉及Python樹(shù)結(jié)構(gòu)的定義、遍歷及統(tǒng)計(jì)等相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • 使用tensorflow實(shí)現(xiàn)矩陣分解方式

    使用tensorflow實(shí)現(xiàn)矩陣分解方式

    今天小編就為大家分享一篇使用tensorflow實(shí)現(xiàn)矩陣分解方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02

最新評(píng)論

会昌县| 房山区| 慈溪市| 穆棱市| 南陵县| 嵊泗县| 政和县| 杭锦旗| 前郭尔| 永年县| 阿拉善左旗| 淮安市| 夹江县| 高密市| 蒙自县| 湛江市| 公主岭市| 曲麻莱县| 桐柏县| 凌海市| 治多县| 桦川县| 上高县| 专栏| 永福县| 林口县| 博兴县| 和田市| 武汉市| 宜兰县| 靖安县| 登封市| 定日县| 兴文县| 离岛区| 拉萨市| 涞水县| 沅江市| 贺兰县| 六枝特区| 临夏县|