zoukankan      html  css  js  c++  java
  • 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)基于用户名和密码的连接

    复制代码
     1 import paramiko
     2  
     3 # 创建SSH对象
     4 ssh = paramiko.SSHClient()
     5 # 允许连接不在know_hosts文件中的主机
     6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
     7 # 连接服务器
     8 ssh.connect(hostname='c1.salt.com', port=22, username='GSuser', password='123')
     9 # 执行命令
    10 stdin, stdout, stderr = ssh.exec_command('ls')
    11 # 获取命令结果
    12 result = stdout.read()
    13 # 关闭连接
    14 ssh.close()
    复制代码

      SSHClient 封装 Transport

    复制代码
     1 import paramiko
     2  
     3 transport = paramiko.Transport(('hostname', 22))
     4 transport.connect(username='GSuser', password='123')
     5  
     6 ssh = paramiko.SSHClient()
     7 ssh._transport = transport
     8  
     9 stdin, stdout, stderr = ssh.exec_command('df')
    10 print(stdout.read())
    11  
    12 transport.close()
    复制代码

      (2)基于公钥秘钥连接

    复制代码
     1 import paramiko
     2  
     3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
     4 # 创建SSH对象
     5 ssh = paramiko.SSHClient()
     6 # 允许连接不在know_hosts文件中的主机
     7 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
     8 # 连接服务器
     9 ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', key=private_key)
    10 # 执行命令
    11 stdin, stdout, stderr = ssh.exec_command('df')
    12 # 获取命令结果
    13 result = stdout.read()
    14 # 关闭连接
    15 ssh.close()
    复制代码

      SSHClient 封装Transport

    复制代码
    1 import paramiko
    2  
    3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
    4 transport = paramiko.Transport(('hostname', 22))
    5 transport.connect(username='wupeiqi', pkey=private_key)
    6 ssh = paramiko.SSHClient()
    7 ssh._transport = transport
    8 stdin, stdout, stderr = ssh.exec_command('df')
    9 transport.close()
    复制代码

    SFTPClient:

      用于连接远程服务器并进行上传下载功能。

    (1)基于用户名密码上传下载

    复制代码
     1 import paramiko
     2  
     3 transport = paramiko.Transport(('hostname',22))
     4 transport.connect(username='GSuser',password='123')
     5  
     6 sftp = paramiko.SFTPClient.from_transport(transport)
     7 # 将location.py 上传至服务器 /tmp/test.py
     8 sftp.put('/tmp/location.py', '/tmp/test.py')
     9 # 将remove_path 下载到本地 local_path
    10 sftp.get('remove_path', 'local_path')
    11  
    12 transport.close()
    复制代码

    (2)基于公钥秘钥上传下载

    复制代码
     1 import paramiko
     2  
     3 private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
     4  
     5 transport = paramiko.Transport(('hostname', 22))
     6 transport.connect(username='GSuser', pkey=private_key )
     7  
     8 sftp = paramiko.SFTPClient.from_transport(transport)
     9 # 将location.py 上传至服务器 /tmp/test.py
    10 sftp.put('/tmp/location.py', '/tmp/test.py')
    11 # 将remove_path 下载到本地 local_path
    12 sftp.get('remove_path', 'local_path')
    13  
    14 transport.close()
    复制代码

      Demo: 实现远程命令执行和文件上传

    复制代码
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 import paramiko
     4  
     5 class SSHConnection(object):
     6  
     7     def __init__(self, host='192.168.12.68', port=22, username='locojoy',pwd='123321QQ!'):
     8         self.host = host
     9         self.port = port
    10         self.username = username
    11         self.pwd = pwd
    12         self.__k = None
    13  
    14     def run(self):
    15         self.connect()  # 连接远程服务器
    16         self.upload('db.py','/tmp/1.py')  # 将本地的db.py文件上传到远端服务器的/tmp/目录下并改名为1.py
    17         self.cmd('df')  # 执行df 命令
    18         self.close()    # 关闭连接
    19  
    20     def connect(self):
    21         transport = paramiko.Transport((self.host, self.port))
    22         transport.connect(username=self.username, password=self.pwd)
    23         self.__transport = transport
    24  
    25     def close(self):
    26         self.__transport.close()
    27  
    28     def upload(self,local_path,target_path):
    29         sftp = paramiko.SFTPClient.from_transport(self.__transport)
    30         sftp.put(local_path,target_path)
    31  
    32     def cmd(self, command):
    33         ssh = paramiko.SSHClient()
    34         ssh._transport = self.__transport
    35         # 执行命令
    36         stdin, stdout, stderr = ssh.exec_command(command)
    37         # 获取命令结果
    38         result = stdout.read()
    39         print(result)
    40         return result
    41  
    42 obj = SSHConnection()
    43 obj.run()
    复制代码

      paramiko在堡垒机中的应用

    (1)简单实例:远程连接一台主机,操作命令,linux版本,输入终端为回车则发送命令。不支持tab补全功能。

    复制代码
     1 import paramiko, sys, os, socket, select, getpass
     2 from paramiko.py3compat import u   # 在python3中是这样使用的,如果在Python2中则注释这行
     3  
     4 # 这个程序依赖于终端,只能在Liunx下运行,windows用其他的方式
     5  
     6 tran = paramiko.Transport(('192.168.12.68', 22,))
     7 tran.start_client()
     8 tran.auth_password('locojoy', '123321QQ!')
     9  
    10 # 打开一个通道
    11 chan = tran.open_session()
    12 # 获取一个终端
    13 chan.get_pty()
    14 # 激活器
    15 chan.invoke_shell()
    16  
    17 # 原始的方法利用终端进行收发消息
    18 # 利用sys.stdin,肆意妄为执行操作
    19 # 用户在终端输入内容,并将内容发送至远程服务器
    20 # 远程服务器执行命令,并将结果返回
    21 # 用户终端显示内容
    22  
    23 while True:
    24     # 监视用户输入和服务器返回数据
    25     # sys.stdin 处理用户输入
    26     # chan 是之前创建的通道,用于接收服务器返回信息
    27     # 通过select监听终端(输入输出),一旦变化,就将拿到的数据发送给服务器
    28     # 通过监听socket句柄,如果有变化表示服务器要给我发消息
    29     readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
    30     # 通过select.select 监听chan(打开的通道(和远程服务器连接的状态)), sys.stdin(输入),一旦变化就写入readable
    31     # 当chan变化时,加入到readable,远程服务器发送内容过来
    32     if chan in readable:
    33         try:
    34             x = u(chan.recv(1024))  # Python3用这个
    35             # x = chan.recv(1024)  Python2使用这个
    36             if len(x) == 0:
    37                 print('
    *** EOF
    ')
    38                 break
    39             sys.stdout.write(x)   # 写入缓冲区
    40             sys.stdout.flush()    # 刷新,将缓冲区内容显示出来
    41         except socket.timeout:
    42             pass
    43     # 当sys.stdin 放入readable中时,将获取到的内容发送到远程服务器
    44     if sys.stdin in readable:
    45         inp = sys.stdin.readline()
    46         chan.sendall(inp)
    47  
    48 chan.close()
    49 tran.close()
    复制代码

    (2)每按一个键就发送记录,并支持tab自动补全

    复制代码
     1 import paramiko, sys, os, socket, select, getpass, termios, tty
     2 from paramiko.py3compat import u
     3  
     4 tran = paramiko.Transport(('10.211.55.4', 22,))
     5 tran.start_client()
     6 tran.auth_password('wupeiqi', '123')
     7 # 打开一个通道
     8 chan = tran.open_session()
     9 # 获取一个终端
    10 chan.get_pty()
    11 # 激活器
    12 chan.invoke_shell()
    13  
    14 # 获取原tty属性
    15 oldtty = termios.tcgetattr(sys.stdin)
    16 try:
    17     # 为tty设置新属性
    18     # 默认当前tty设备属性:
    19     #   输入一行回车,执行
    20     #   CTRL+C 进程退出,遇到特殊字符,特殊处理。
    21     # 这是为原始模式,不认识所有特殊符号
    22     # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
    23     tty.setraw(sys.stdin.fileno())  # 恢复终端原始状态,每按一个键就发送
    24     chan.settimeout(0.0)
    25  
    26     while True:
    27         # 监视 用户输入 和 远程服务器返回数据(socket)
    28         # 阻塞,直到句柄可读
    29         r, w, e = select.select([chan, sys.stdin], [], [], 1)
    30         if chan in r:  # 获取服务返回的内容
    31             try:
    32                 x = u(chan.recv(1024))
    33                 if len(x) == 0:
    34                     print('
    *** EOF
    ')
    35                     break
    36                 sys.stdout.write(x)
    37                 sys.stdout.flush()
    38             except socket.timeout:
    39                 pass
    40         if sys.stdin in r: # 发送命令
    41             x = sys.stdin.read(1) # 读取一个字符
    42             if len(x) == 0:
    43                 break
    44             chan.send(x) # 发送一个字符
    45  
    46 finally:
    47     # 重新设置终端属性,将终端状态还原
    48     termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
    49  
    50 chan.close()
    51 tran.close()
    复制代码
     
    分类: python
  • 相关阅读:
    Good Bye 2014 B. New Year Permutation(floyd )
    hdu 5147 Sequence II (树状数组 求逆序数)
    POJ 1696 Space Ant (极角排序)
    POJ 2398 Toy Storage (叉积判断点和线段的关系)
    hdu 2897 邂逅明下 (简单巴什博弈)
    poj 1410 Intersection (判断线段与矩形相交 判线段相交)
    HDU 3400 Line belt (三分嵌套)
    Codeforces Round #279 (Div. 2) C. Hacking Cypher (大数取余)
    Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
    hdu 1576 A/B (求逆元)
  • 原文地址:https://www.cnblogs.com/lgj8/p/12981803.html
Copyright © 2011-2022 走看看