zoukankan      html  css  js  c++  java
  • Python模块之paramiko

    Paramiko

      paramiko模块,基于SSH用于连接远程服务器并执行相关操作。

    一、安装

    1 pip3 install paramiko

    二、使用

    SSHClient

    用于连接远程服务器并执行基本命令

    基于用户名密码连接:

     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='wupeiqi', password='123')
     9    
    10 # 执行命令
    11 stdin, stdout, stderr = ssh.exec_command('ls')
    12 # 获取命令结果
    13 result = stdout.read()
    14    
    15 # 关闭连接
    16 ssh.close()
     1 import paramiko
     2 
     3 transport = paramiko.Transport(('hostname', 22))
     4 transport.connect(username='wupeiqi', 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()
    13 
    14 SSHClient 封装 Transport
    SSHClient 封装 Transport

    基于公钥密钥连接:

    import paramiko
      
    private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
      
    # 创建SSH对象
    ssh = paramiko.SSHClient()
    # 允许连接不在know_hosts文件中的主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 连接服务器
    ssh.connect(hostname='c1.salt.com', port=22, username='wupeiqi', key=private_key)
      
    # 执行命令
    stdin, stdout, stderr = ssh.exec_command('df')
    # 获取命令结果
    result = stdout.read()
      
    # 关闭连接
    ssh.close()
     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='wupeiqi', pkey=private_key)
     7 
     8 ssh = paramiko.SSHClient()
     9 ssh._transport = transport
    10 
    11 stdin, stdout, stderr = ssh.exec_command('df')
    12 
    13 transport.close()
    14 
    15 SSHClient 封装 Transport
    SSHClient 封装 Transport
     1 import paramiko
     2 from io import StringIO
     3 
     4 key_str = """-----BEGIN RSA PRIVATE KEY-----
     5 MIIEpQIBAAKCAQEAq7gLsqYArAFco02/55IgNg0r7NXOtEM3qXpb/dabJ5Uyky/8
     6 NEHhFiQ7deHIRIuTW5Zb0kD6h6EBbVlUMBmwJrC2oSzySLU1w+ZNfH0PE6W6fans
     7 H80whhuc/YgP+fjiO+VR/gFcqib8Rll5UfYzf5H8uuOnDeIXGCVgyHQSmt8if1+e
     8 7hn1MVO1Lrm9Fco8ABI7dyv8/ZEwoSfh2C9rGYgA58LT1FkBRkOePbHD43xNfAYC
     9 tfLvz6LErMnwdOW4sNMEWWAWv1fsTB35PAm5CazfKzmam9n5IQXhmUNcNvmaZtvP
    10 c4f4g59mdsaWNtNaY96UjOfx83Om86gmdkKcnwIDAQABAoIBAQCnDBGFJuv8aA7A
    11 ZkBLe+GN815JtOyye7lIS1n2I7En3oImoUWNaJEYwwJ8+LmjxMwDCtAkR0XwbvY+
    12 c+nsKPEtkjb3sAu6I148RmwWsGncSRqUaJrljOypaW9dS+GO4Ujjz3/lw1lrxSUh
    13 IqVc0E7kyRW8kP3QCaNBwArYteHreZFFp6XmtKMtXaEA3saJYILxaaXlYkoRi4k8
    14 S2/K8aw3ZMR4tDCOfB4o47JaeiA/e185RK3A+mLn9xTDhTdZqTQpv17/YRPcgmwz
    15 zu30fhVXQT/SuI0sO+bzCO4YGoEwoBX718AWhdLJFoFq1B7k2ZEzXTAtjEXQEWm6
    16 01ndU/jhAasdfasdasdfasdfa3eraszxqwefasdfadasdffsFIfAsjQb4HdkmHuC
    17 OeJrJOd+CYvdEeqJJNnF6AbHyYHIECkj0Qq1kEfLOEsqzd5nDbtkKBte6M1trbjl
    18 HtJ2Yb8w6o/q/6Sbj7wf/cW3LIYEdeVCjScozVcQ9R83ea05J+QOAr4nAoGBAMaq
    19 UzLJfLNWZ5Qosmir2oHStFlZpxspax/ln7DlWLW4wPB4YJalSVovF2Buo8hr8X65
    20 lnPiE41M+G0Z7icEXiFyDBFDCtzx0x/RmaBokLathrFtI81UCx4gQPLaSVNMlvQA
    21 539GsubSrO4LpHRNGg/weZ6EqQOXvHvkUkm2bDDJAoGATytFNxen6GtC0ZT3SRQM
    22 WYfasdf3xbtuykmnluiofasd2sfmjnljkt7khghmghdasSDFGQfgaFoKfaawoYeH
    23 C2XasVUsVviBn8kPSLSVBPX4JUfQmA6h8HsajeVahxN1U9e0nYJ0sYDQFUMTS2t8
    24 RT57+WK/0ONwTWHdu+KnaJECgYEAid/ta8LQC3p82iNAZkpWlGDSD2yb/8rH8NQg
    25 9tjEryFwrbMtfX9qn+8srx06B796U3OjifstjJQNmVI0qNlsJpQK8fPwVxRxbJS/
    26 pMbNICrf3sUa4sZgDOFfkeuSlgACh4cVIozDXlR59Z8Y3CoiW0uObEgvMDIfenAj
    27 98pl3ZkCgYEAj/UCSni0dwX4pnKNPm6LUgiS7QvIgM3H9piyt8aipQuzBi5LUKWw
    28 DlQC4Zb73nHgdREtQYYXTu7p27Bl0Gizz1sW2eSgxFU8eTh+ucfVwOXKAXKU5SeI
    29 +MbuBfUYQ4if2N/BXn47+/ecf3A4KgB37Le5SbLDddwCNxGlBzbpBa0=
    30 -----END RSA PRIVATE KEY-----"""
    31 
    32 private_key = paramiko.RSAKey(file_obj=StringIO(key_str))
    33 transport = paramiko.Transport(('10.0.1.40', 22))
    34 transport.connect(username='wupeiqi', pkey=private_key)
    35 
    36 ssh = paramiko.SSHClient()
    37 ssh._transport = transport
    38 
    39 stdin, stdout, stderr = ssh.exec_command('df')
    40 result = stdout.read()
    41 
    42 transport.close()
    43 
    44 print(result)
    45 
    46 基于私钥字符进行连接
    基于私钥字符进行连接

    SFTPClient

    用于连接远程服务器并执行上传下载

    基于用户名密码上传下载:

     1 import paramiko
     2   
     3 transport = paramiko.Transport(('hostname',22))
     4 transport.connect(username='wupeiqi',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()

    基于公钥密钥上传下载:

     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='wupeiqi', 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()
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 import paramiko
     4 import uuid
     5 
     6 class SSHConnection(object):
     7 
     8     def __init__(self, host='172.16.103.191', port=22, username='wupeiqi',pwd='123'):
     9         self.host = host
    10         self.port = port
    11         self.username = username
    12         self.pwd = pwd
    13         self.__k = None
    14 
    15     def create_file(self):
    16         file_name = str(uuid.uuid4())
    17         with open(file_name,'w') as f:
    18             f.write('sb')
    19         return file_name
    20 
    21     def run(self):
    22         self.connect()
    23         self.upload('/home/wupeiqi/tttttttttttt.py')
    24         self.rename('/home/wupeiqi/tttttttttttt.py', '/home/wupeiqi/ooooooooo.py)
    25         self.close()
    26 
    27     def connect(self):
    28         transport = paramiko.Transport((self.host,self.port))
    29         transport.connect(username=self.username,password=self.pwd)
    30         self.__transport = transport
    31 
    32     def close(self):
    33 
    34         self.__transport.close()
    35 
    36     def upload(self,target_path):
    37         # 连接,上传
    38         file_name = self.create_file()
    39 
    40         sftp = paramiko.SFTPClient.from_transport(self.__transport)
    41         # 将location.py 上传至服务器 /tmp/test.py
    42         sftp.put(file_name, target_path)
    43 
    44     def rename(self, old_path, new_path):
    45 
    46         ssh = paramiko.SSHClient()
    47         ssh._transport = self.__transport
    48         # 执行命令
    49         cmd = "mv %s %s" % (old_path, new_path,)
    50         stdin, stdout, stderr = ssh.exec_command(cmd)
    51         # 获取命令结果
    52         result = stdout.read()
    53 
    54     def cmd(self, command):
    55         ssh = paramiko.SSHClient()
    56         ssh._transport = self.__transport
    57         # 执行命令
    58         stdin, stdout, stderr = ssh.exec_command(command)
    59         # 获取命令结果
    60         result = stdout.read()
    61         return result
    62         
    63 
    64 
    65 ha = SSHConnection()
    66 ha.run()
    67 
    68 Demo
    demo
    1 # 对于更多限制命令,需要在系统中设置
    2 /etc/sudoers
    3   
    4 Defaults    requiretty
    5 Defaults:cmdb    !requiretty
    View Code
     1 import paramiko
     2 import uuid
     3 
     4 class SSHConnection(object):
     5 
     6     def __init__(self, host='192.168.11.61', port=22, username='alex',pwd='alex3714'):
     7         self.host = host
     8         self.port = port
     9         self.username = username
    10         self.pwd = pwd
    11         self.__k = None
    12 
    13     def run(self):
    14         self.connect()
    15         pass
    16         self.close()
    17 
    18     def connect(self):
    19         transport = paramiko.Transport((self.host,self.port))
    20         transport.connect(username=self.username,password=self.pwd)
    21         self.__transport = transport
    22 
    23     def close(self):
    24         self.__transport.close()
    25 
    26     def cmd(self, command):
    27         ssh = paramiko.SSHClient()
    28         ssh._transport = self.__transport
    29         # 执行命令
    30         stdin, stdout, stderr = ssh.exec_command(command)
    31         # 获取命令结果
    32         result = stdout.read()
    33         return result
    34 
    35     def upload(self,local_path, target_path):
    36         # 连接,上传
    37         sftp = paramiko.SFTPClient.from_transport(self.__transport)
    38         # 将location.py 上传至服务器 /tmp/test.py
    39         sftp.put(local_path, target_path)
    40 
    41 ssh = SSHConnection()
    42 ssh.connect()
    43 r1 = ssh.cmd('df')
    44 ssh.upload('s2.py', "/home/alex/s7.py")
    45 ssh.close()
    46 
    47 Demo
    Demo

    堡垒机

    堡垒机执行流程:

    1. 管理员为用户在服务器上创建账号(将公钥放置服务器,或者使用用户名密码)
    2. 用户登陆堡垒机,输入堡垒机用户名密码,现实当前用户管理的服务器列表
    3. 用户选择服务器,并自动登陆
    4. 执行操作并同时将用户操作记录

    注:配置.brashrc实现ssh登陆后自动执行脚本,如:/usr/bin/python /home/wupeiqi/menu.py

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 from sqlalchemy import create_engine, and_, or_, func, Table
     5 from sqlalchemy.ext.declarative import declarative_base
     6 from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, DateTime
     7 from sqlalchemy.orm import sessionmaker, relationship
     8 
     9 Base = declarative_base()  # 生成一个SqlORM 基类
    10 
    11 
    12 class Host(Base):
    13     __tablename__ = 'host'
    14     id = Column(Integer, primary_key=True, autoincrement=True)
    15     hostname = Column(String(64), unique=True, nullable=False)
    16     ip_addr = Column(String(128), unique=True, nullable=False)
    17     port = Column(Integer, default=22)
    18 
    19 
    20 class HostUser(Base):
    21     __tablename__ = 'host_user'
    22     id = Column(Integer, primary_key=True, autoincrement=True)
    23     username = Column(String(64), unique=True, nullable=False)
    24     AuthTypes = [
    25         ('p', 'SSH/Password'),
    26         ('r', 'SSH/KEY'),
    27     ]
    28     auth_type = Column(String(16))
    29     cert = Column(String(255))
    30 
    31     host_id = Column(Integer, ForeignKey('host.id'))
    32 
    33     __table_args__ = (
    34         UniqueConstraint('host_id', 'username', name='_host_username_uc'),
    35     )
    36 
    37 
    38 class Group(Base):
    39     __tablename__ = 'group'
    40     id = Column(Integer, primary_key=True, autoincrement=True)
    41     name = Column(String(64), unique=True, nullable=False)
    42 
    43 
    44 class UserProfile(Base):
    45     __tablename__ = 'user_profile'
    46     id = Column(Integer, primary_key=True, autoincrement=True)
    47     username = Column(String(64), unique=True, nullable=False)
    48     password = Column(String(255), nullable=False)
    49 
    50 
    51 class Group2UserProfile(Base):
    52     __tablename__ = 'group_2_user_profile'
    53     id = Column(Integer, primary_key=True, autoincrement=True)
    54     user_profile_id = Column(Integer, ForeignKey('user_profile.id'))
    55     group_id = Column(Integer, ForeignKey('group.id'))
    56     __table_args__ = (
    57         UniqueConstraint('user_profile_id', 'group_id', name='ux_user_group'),
    58     )
    59 
    60 
    61 class Group2HostUser(Base):
    62     __tablename__ = 'group_2_host_user'
    63     id = Column(Integer, primary_key=True, autoincrement=True)
    64     host_user_id = Column(Integer, ForeignKey('host_user.id'))
    65     group_id = Column(Integer, ForeignKey('group.id'))
    66     __table_args__ = (
    67         UniqueConstraint('group_id', 'host_user_id', name='ux_group_host_user'),
    68     )
    69 
    70 
    71 class UserProfile2HostUser(Base):
    72     __tablename__ = 'user_profile_2_host_user'
    73     id = Column(Integer, primary_key=True, autoincrement=True)
    74     host_user_id = Column(Integer, ForeignKey('host_user.id'))
    75     user_profile_id = Column(Integer, ForeignKey('user_profile.id'))
    76     __table_args__ = (
    77         UniqueConstraint('user_profile_id', 'host_user_id', name='ux_user_host_user'),
    78     )
    79 
    80 
    81 class AuditLog(Base):
    82     __tablename__ = 'audit_log'
    83     id = Column(Integer, primary_key=True, autoincrement=True)
    84 
    85     action_choices2 = [
    86         (u'cmd', u'CMD'),
    87         (u'login', u'Login'),
    88         (u'logout', u'Logout'),
    89     ]
    90     action_type = Column(String(16))
    91     cmd = Column(String(255))
    92     date = Column(DateTime)
    93     user_profile_id = Column(Integer, ForeignKey('user_profile.id'))
    94     host_user_id = Column(Integer, ForeignKey('host_user.id'))
    95 
    96 表结构示例
    表结构示例

    实现过程

    1、前戏

     1 import paramiko
     2 import sys
     3 import os
     4 import socket
     5 import select
     6 import getpass
     7  
     8 tran = paramiko.Transport(('10.211.55.4', 22,))
     9 tran.start_client()
    10 tran.auth_password('wupeiqi', '123')
    11  
    12 # 打开一个通道
    13 chan = tran.open_session()
    14 # 获取一个终端
    15 chan.get_pty()
    16 # 激活器
    17 chan.invoke_shell()
    18  
    19 #########
    20 # 利用sys.stdin,肆意妄为执行操作
    21 # 用户在终端输入内容,并将内容发送至远程服务器
    22 # 远程服务器执行命令,并将结果返回
    23 # 用户终端显示内容
    24 #########
    25  
    26 chan.close()
    27 tran.close()

    2、肆意妄为(一)

     1 import paramiko
     2 import sys
     3 import os
     4 import socket
     5 import select
     6 import getpass
     7 from paramiko.py3compat import u
     8  
     9 tran = paramiko.Transport(('10.211.55.4', 22,))
    10 tran.start_client()
    11 tran.auth_password('wupeiqi', '123')
    12  
    13 # 打开一个通道
    14 chan = tran.open_session()
    15 # 获取一个终端
    16 chan.get_pty()
    17 # 激活器
    18 chan.invoke_shell()
    19  
    20 while True:
    21     # 监视用户输入和服务器返回数据
    22     # sys.stdin 处理用户输入
    23     # chan 是之前创建的通道,用于接收服务器返回信息
    24     readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
    25     if chan in readable:
    26         try:
    27             x = u(chan.recv(1024))
    28             if len(x) == 0:
    29                 print('
    *** EOF
    ')
    30                 break
    31             sys.stdout.write(x)
    32             sys.stdout.flush()
    33         except socket.timeout:
    34             pass
    35     if sys.stdin in readable:
    36         inp = sys.stdin.readline()
    37         chan.sendall(inp)
    38  
    39 chan.close()
    40 tran.close()
    View Code
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 import paramiko
     5 import sys
     6 import os
     7 import socket
     8 import select
     9 import getpass
    10 from paramiko.py3compat import u
    11 
    12 
    13 default_username = getpass.getuser()
    14 username = input('Username [%s]: ' % default_username)
    15 if len(username) == 0:
    16     username = default_username
    17 
    18 
    19 hostname = input('Hostname: ')
    20 if len(hostname) == 0:
    21     print('*** Hostname required.')
    22     sys.exit(1)
    23 
    24 tran = paramiko.Transport((hostname, 22,))
    25 tran.start_client()
    26 
    27 default_auth = "p"
    28 auth = input('Auth by (p)assword or (r)sa key[%s] ' % default_auth)
    29 if len(auth) == 0:
    30     auth = default_auth
    31 
    32 if auth == 'r':
    33     default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
    34     path = input('RSA key [%s]: ' % default_path)
    35     if len(path) == 0:
    36         path = default_path
    37     try:
    38         key = paramiko.RSAKey.from_private_key_file(path)
    39     except paramiko.PasswordRequiredException:
    40         password = getpass.getpass('RSA key password: ')
    41         key = paramiko.RSAKey.from_private_key_file(path, password)
    42     tran.auth_publickey(username, key)
    43 else:
    44     pw = getpass.getpass('Password for %s@%s: ' % (username, hostname))
    45     tran.auth_password(username, pw)
    46 
    47 
    48 
    49 # 打开一个通道
    50 chan = tran.open_session()
    51 # 获取一个终端
    52 chan.get_pty()
    53 # 激活器
    54 chan.invoke_shell()
    55 
    56 while True:
    57     # 监视用户输入和服务器返回数据
    58     # sys.stdin 处理用户输入
    59     # chan 是之前创建的通道,用于接收服务器返回信息
    60     readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
    61     if chan in readable:
    62         try:
    63             x = u(chan.recv(1024))
    64             if len(x) == 0:
    65                 print('
    *** EOF
    ')
    66                 break
    67             sys.stdout.write(x)
    68             sys.stdout.flush()
    69         except socket.timeout:
    70             pass
    71     if sys.stdin in readable:
    72         inp = sys.stdin.readline()
    73         chan.sendall(inp)
    74 
    75 chan.close()
    76 tran.close()
    77 
    78 完整示例(一)
    完整示例(一)

    3、肆意妄为(二)

     1 import paramiko
     2 import sys
     3 import os
     4 import socket
     5 import select
     6 import getpass
     7 import termios
     8 import tty
     9 from paramiko.py3compat import u
    10  
    11 tran = paramiko.Transport(('10.211.55.4', 22,))
    12 tran.start_client()
    13 tran.auth_password('wupeiqi', '123')
    14  
    15 # 打开一个通道
    16 chan = tran.open_session()
    17 # 获取一个终端
    18 chan.get_pty()
    19 # 激活器
    20 chan.invoke_shell()
    21  
    22  
    23 # 获取原tty属性
    24 oldtty = termios.tcgetattr(sys.stdin)
    25 try:
    26     # 为tty设置新属性
    27     # 默认当前tty设备属性:
    28     #   输入一行回车,执行
    29     #   CTRL+C 进程退出,遇到特殊字符,特殊处理。
    30  
    31     # 这是为原始模式,不认识所有特殊符号
    32     # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
    33     tty.setraw(sys.stdin.fileno())
    34     chan.settimeout(0.0)
    35  
    36     while True:
    37         # 监视 用户输入 和 远程服务器返回数据(socket)
    38         # 阻塞,直到句柄可读
    39         r, w, e = select.select([chan, sys.stdin], [], [], 1)
    40         if chan in r:
    41             try:
    42                 x = u(chan.recv(1024))
    43                 if len(x) == 0:
    44                     print('
    *** EOF
    ')
    45                     break
    46                 sys.stdout.write(x)
    47                 sys.stdout.flush()
    48             except socket.timeout:
    49                 pass
    50         if sys.stdin in r:
    51             x = sys.stdin.read(1)
    52             if len(x) == 0:
    53                 break
    54             chan.send(x)
    55  
    56 finally:
    57     # 重新设置终端属性
    58     termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
    59  
    60  
    61 chan.close()
    62 tran.close()
    View Code
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 import paramiko
     4 import sys
     5 import os
     6 import socket
     7 import getpass
     8 import termios
     9 import tty
    10 import select
    11 from paramiko.py3compat import u
    12 
    13 
    14 def interactive_shell(chan):
    15     # 获取原tty属性
    16     oldtty = termios.tcgetattr(sys.stdin)
    17     try:
    18         # 为tty设置新属性
    19         # 默认当前tty设备属性:
    20         #   输入一行回车,执行
    21         #   CTRL+C 进程退出,遇到特殊字符,特殊处理。
    22 
    23         # 这是为原始模式,不认识所有特殊符号
    24         # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
    25         tty.setraw(sys.stdin.fileno())
    26         tty.setcbreak(sys.stdin.fileno())
    27         chan.settimeout(0.0)
    28         while True:
    29             r, w, e = select.select([chan, sys.stdin], [], [])
    30             if chan in r:
    31                 try:
    32                     x = u(chan.recv(1024))
    33                     if len(x) == 0:
    34                         sys.stdout.write('
    *** 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 
    51 def run():
    52     hostname = input('请输入主机名: ')
    53     tran = paramiko.Transport((hostname, 22,))
    54     tran.start_client()
    55 
    56     username = input('请输入用户名: ')
    57     auth = input('请输入密码进行验证(p) 或 (r)sa Key进行验证?')
    58     if auth == 'r':
    59         path = input('请输入RSA key 路径: ')
    60         try:
    61             key = paramiko.RSAKey.from_private_key_file(path)
    62         except paramiko.PasswordRequiredException:
    63             password = getpass.getpass('RSA key password: ')
    64             key = paramiko.RSAKey.from_private_key_file(path, password)
    65         tran.auth_publickey(username, key)
    66     else:
    67         pw = getpass.getpass('请输入密码 %s@%s: ' % (username, hostname))
    68         tran.auth_password(username, pw)
    69 
    70     # 打开一个通道
    71     chan = tran.open_session()
    72     # 获取一个终端
    73     chan.get_pty()
    74     # 激活器
    75     chan.invoke_shell()
    76 
    77     interactive_shell(chan)
    78 
    79     chan.close()
    80     tran.close()
    81 
    82 
    83 if __name__ == '__main__':
    84     run()
    85 
    86 基于Passwd或者RSA进行登陆操作
    基于Passwd或者RSA进行登陆操作
     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 import paramiko
     4 import sys
     5 import os
     6 import socket
     7 import getpass
     8 import termios
     9 import tty
    10 import select
    11 from paramiko.py3compat import u
    12 
    13 
    14 def interactive_shell(chan):
    15     # 获取原tty属性
    16     oldtty = termios.tcgetattr(sys.stdin)
    17     try:
    18         # 为tty设置新属性
    19         # 默认当前tty设备属性:
    20         # 输入一行回车,执行
    21         # CTRL+C 进程退出,遇到特殊字符,特殊处理。
    22 
    23         # 这是为原始模式,不认识所有特殊符号
    24         # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
    25         tty.setraw(sys.stdin.fileno())
    26         tty.setcbreak(sys.stdin.fileno())
    27         chan.settimeout(0.0)
    28         while True:
    29             r, w, e = select.select([chan, sys.stdin], [], [])
    30             if chan in r:
    31                 try:
    32                     x = u(chan.recv(1024))
    33                     if len(x) == 0:
    34                         sys.stdout.write('
    *** 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 
    51 def run():
    52     db_dict = {
    53         'c1.salt.com': {
    54             'root': {'user': 'root', 'auth': 'r', "cert": 'key路径'},
    55             'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
    56         },
    57         'c2.salt.com': {
    58             'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
    59         },
    60 
    61     }
    62 
    63     for row in db_dict.keys():
    64         print(row)
    65 
    66     hostname = input('请选择主机: ')
    67     tran = paramiko.Transport((hostname, 22,))
    68     tran.start_client()
    69 
    70     for item in db_dict[hostname].keys():
    71         print(item)
    72 
    73     username = input('请输入用户: ')
    74 
    75     user_dict = db_dict[hostname][username]
    76     if username['auth'] == 'r':
    77         key = paramiko.RSAKey.from_private_key_file(user_dict['cert'])
    78         tran.auth_publickey(username, key)
    79     else:
    80         pw = user_dict['cert']
    81         tran.auth_password(username, pw)
    82 
    83     # 打开一个通道
    84     chan = tran.open_session()
    85     # 获取一个终端
    86     chan.get_pty()
    87     # 激活器
    88     chan.invoke_shell()
    89 
    90     interactive_shell(chan)
    91 
    92     chan.close()
    93     tran.close()
    94 
    95 
    96 if __name__ == '__main__':
    97     run()
    98 
    99 提示用户选择主机和用户
    提示用户选择主机和用户
      1 #!/usr/bin/env python
      2 # -*- coding:utf-8 -*-
      3 import paramiko
      4 import sys
      5 import os
      6 import socket
      7 import getpass
      8 import termios
      9 import tty
     10 import select
     11 from paramiko.py3compat import u
     12 
     13 
     14 def interactive_shell(chan):
     15     # 获取原tty属性
     16     oldtty = termios.tcgetattr(sys.stdin)
     17     try:
     18         # 为tty设置新属性
     19         # 默认当前tty设备属性:
     20         # 输入一行回车,执行
     21         # CTRL+C 进程退出,遇到特殊字符,特殊处理。
     22 
     23         # 这是为原始模式,不认识所有特殊符号
     24         # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
     25         tty.setraw(sys.stdin.fileno())
     26         tty.setcbreak(sys.stdin.fileno())
     27         chan.settimeout(0.0)
     28 
     29         log = open('handle.log', 'a+', encoding='utf-8')
     30         flag = False
     31         temp_list = []
     32 
     33         while True:
     34             r, w, e = select.select([chan, sys.stdin], [], [])
     35             if chan in r:
     36                 try:
     37                     x = u(chan.recv(1024))
     38                     if len(x) == 0:
     39                         sys.stdout.write('
    *** EOF
    ')
     40                         break
     41                     # 如果用户上一次点击的是tab键,则获取返回的内容写入在记录中
     42                     if flag:
     43                         if x.startswith('
    '):
     44                             pass
     45                         else:
     46                             temp_list.append(x)
     47                         flag = False
     48                     sys.stdout.write(x)
     49                     sys.stdout.flush()
     50                 except socket.timeout:
     51                     pass
     52             if sys.stdin in r:
     53                 # 读取用户在终端数据每一个字符
     54                 x = sys.stdin.read(1)
     55                 if len(x) == 0:
     56                     break
     57                 # 如果用户点击TAB键
     58                 if x == '	':
     59                     flag = True
     60                 else:
     61                     # 未点击TAB键,则将每个操作字符记录添加到列表中,以便之后写入文件
     62                     temp_list.append(x)
     63 
     64                 # 如果用户敲回车,则将操作记录写入文件
     65                 if x == '
    ':
     66                     log.write(''.join(temp_list))
     67                     log.flush()
     68                     temp_list.clear()
     69                 chan.send(x)
     70 
     71     finally:
     72         # 重新设置终端属性
     73         termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
     74 
     75 
     76 def run():
     77     db_dict = {
     78         'c1.salt.com': {
     79             'root': {'user': 'root', 'auth': 'r', "cert": 'key路径'},
     80             'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
     81         },
     82         'c2.salt.com': {
     83             'root': {'user': 'root', 'auth': 'r', "cert": 'key路径'},
     84             'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
     85         },
     86 
     87     }
     88 
     89     for row in db_dict.keys():
     90         print(row)
     91 
     92     hostname = input('请选择主机: ')
     93     tran = paramiko.Transport((hostname, 22,))
     94     tran.start_client()
     95 
     96     for item in db_dict[hostname].keys():
     97         print(item)
     98 
     99     username = input('请输入用户: ')
    100 
    101     user_dict = db_dict[hostname][username]
    102     if username['auth'] == 'r':
    103         key = paramiko.RSAKey.from_private_key_file(user_dict['cert'])
    104         tran.auth_publickey(username, key)
    105     else:
    106         pw = user_dict['cert']
    107         tran.auth_password(username, pw)
    108 
    109     # 打开一个通道
    110     chan = tran.open_session()
    111     # 获取一个终端
    112     chan.get_pty()
    113     # 激活器
    114     chan.invoke_shell()
    115 
    116     interactive_shell(chan)
    117 
    118     chan.close()
    119     tran.close()
    120 
    121 
    122 if __name__ == '__main__':
    123     run()
    124 
    125 提示用户选择主机和用户(记录操作日志)
    提示用户选择主机和用户(记录操作日志)

    更多参见:paramoko源码 https://github.com/paramiko/paramiko 

    武沛齐:http://www.cnblogs.com/wupeiqi/p/5699254.html

    Alex堡垒机:http://www.cnblogs.com/alex3714/articles/5286889.html 

  • 相关阅读:
    模板为webpack的目录结构
    实例和内置组件
    微信小程序之富文本解析
    微信小程序获取输入框(input)内容
    for循环的语法和执行顺序
    循环
    选择结构(二)
    选择结构
    算术运算
    变量
  • 原文地址:https://www.cnblogs.com/python-nameless/p/6855804.html
Copyright © 2011-2022 走看看