中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python使用paramiko實現ssh的功能詳解

發布時間:2020-08-26 23:53:05 來源:腳本之家 閱讀:236 作者:劉江 欄目:開發技術

個人認為python的paramiko模塊是運維人員必學模塊之一,其ssh登錄功能是旅行居家必備工具。

安裝paramiko很簡單,pip install paramiko就搞定了,其依賴庫會被一并安裝。

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

paramiko模塊提供了ssh及sft進行遠程登錄服務器執行命令和上傳下載文件的功能。

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

# 建立一個sshclient對象
ssh = paramiko.SSHClient()
# 允許將信任的主機自動加入到host_allow 列表,此方法必須放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 調用connect方法連接服務器
ssh.connect(hostname='192.168.2.129', port=22, username='super', password='super')
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df -hl')
# 結果放到stdout中,如果有錯誤將放到stderr中
print(stdout.read().decode())
# 關閉連接
ssh.close()

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

方法1是傳統的連接服務器、執行命令、關閉的一個操作,有時候需要登錄上服務器執行多個操作,比如執行命令、上傳/下載文件,方法1則無法實現,可以通過如下方式來操作

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

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

# 關閉連接
trans.close()

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

# 指定本地的RSA私鑰文件,如果建立密鑰對時設置的有密碼,password為設定的密碼,如無不用指定password參數
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)
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df -hl')
# 結果放到stdout中,如果有錯誤將放到stderr中
print(stdout.read().decode())
# 關閉連接
ssh.close()

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

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

# 指定本地的RSA私鑰文件,如果建立密鑰對時設置的有密碼,password為設定的密碼,如無不用指定password參數
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的對象的transport指定為以上的trans
ssh = paramiko.SSHClient()
ssh._transport = trans

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

# 關閉連接
trans.close()

五、傳文件 SFTP

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

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

六、 實現輸入命令立馬返回結果的功能

以上操作都是基本的連接,如果我們想實現一個類似xshell工具的功能,登錄以后可以輸入命令回車后就返回結果:

import paramiko
import os
import select
import sys

# 建立一個socket
trans = paramiko.Transport(('192.168.2.129', 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='super', password='super')
# 打開一個通道
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()

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

七、上例支持tab自動補全

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

'''
實現一個xshell登錄系統的效果,登錄到系統就不斷輸入命令同時返回結果
支持自動補全,直接調用服務器終端

'''
# 建立一個socket
trans = paramiko.Transport(('192.168.2.129', 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='super', password='super')
# 打開一個通道
channel = trans.open_session()
# 獲取終端
channel.get_pty()
# 激活終端,這樣就可以登錄到終端了,就和我們用類似于xshell登錄系統一樣
channel.invoke_shell()

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

  while True:
    readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
    # 如果是用戶輸入命令了,sys.stdin發生變化
    if sys.stdin in readlist:
      # 獲取輸入的內容,輸入一個字符發送1個字符
      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()
finally:
  # 執行完后將現在的終端屬性恢復為原操作終端屬性
  termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

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

八、 SSH服務端的實現

實現SSH服務端必須繼承ServerInterface,并實現里面相應的方法。具體代碼如下:

import socket
import sys
import threading
import paramiko

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

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

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

  #當認證成功,client會請求打開一個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實例化Transport
  bhSession = paramiko.Transport(client)
  #添加一個RSA密鑰加密會話
  bhSession.add_server_key(host_key)
  server = Server()
  try:
  #啟動SSH服務端
    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)

到此這篇關于python使用paramiko實現ssh的功能詳解的文章就介紹到這了,更多相關python paramiko實現ssh內容請搜索億速云以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持億速云!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

昂仁县| 镇赉县| 策勒县| 南靖县| 资中县| 抚州市| 奉新县| 自贡市| 宁夏| 西丰县| 云安县| 江口县| 肇庆市| 阜城县| 西城区| 江津市| 中牟县| 高尔夫| 万州区| 湖口县| 隆德县| 泰州市| 乌苏市| 百色市| 镇原县| 兰溪市| 北碚区| 崇文区| 会同县| 博罗县| 新田县| 麟游县| 彰武县| 板桥市| 隆子县| 杨浦区| 区。| 崇阳县| 揭阳市| 舞阳县| 侯马市|