Python模块之paramiko

article/2025/10/14 20:39:10

Paramiko

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

一、安装

1 pip3 install paramiko

二、使用

SSHClient

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

基于用户名密码连接:

 1 import paramiko2    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()

 SSHClient 封装 Transport

 1 import paramiko2 3 transport = paramiko.Transport(('hostname', 22))4 transport.connect(username='wupeiqi', password='123')5 6 ssh = paramiko.SSHClient()7 ssh._transport = transport8 9 stdin, stdout, stderr = ssh.exec_command('df')
10 print stdout.read()
11 
12 transport.close()
13 
14 SSHClient 封装 Transport

基于公钥密钥连接:

import paramikoprivate_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()

 SSHClient 封装 Transport

 1 import paramiko2 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

 基于私钥字符进行连接

 1 import paramiko2 from io import StringIO3 4 key_str = """-----BEGIN RSA PRIVATE KEY-----5 MIIEpQIBAAKCAQEAq7gLsqYArAFco02/55IgNg0r7NXOtEM3qXpb/dabJ5Uyky/86 NEHhFiQ7deHIRIuTW5Zb0kD6h6EBbVlUMBmwJrC2oSzySLU1w+ZNfH0PE6W6fans7 H80whhuc/YgP+fjiO+VR/gFcqib8Rll5UfYzf5H8uuOnDeIXGCVgyHQSmt8if1+e8 7hn1MVO1Lrm9Fco8ABI7dyv8/ZEwoSfh2C9rGYgA58LT1FkBRkOePbHD43xNfAYC9 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 paramiko2   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.py8 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 paramiko2   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()

 demo

 1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 import paramiko4 import uuid5 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

 View Code

1 # 对于更多限制命令,需要在系统中设置
2 /etc/sudoers
3   
4 Defaults    requiretty
5 Defaults:cmdb    !requiretty

 Demo

 1 import paramiko2 import uuid3 4 class SSHConnection(object):5 6     def __init__(self, host='192.168.11.61', port=22, username='alex',pwd='alex3714'):7         self.host = host8         self.port = port9         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

堡垒机

堡垒机执行流程:

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

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

 表结构示例

 1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 4 from sqlalchemy import create_engine, and_, or_, func, Table5 from sqlalchemy.ext.declarative import declarative_base6 from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, DateTime7 from sqlalchemy.orm import sessionmaker, relationship8 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 paramiko2 import sys3 import os4 import socket5 import select6 import getpass7  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、肆意妄为(一)

 View Code

 1 import paramiko2 import sys3 import os4 import socket5 import select6 import getpass7 from paramiko.py3compat import u8  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('\r\n*** EOF\r\n')
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()

 完整示例(一)

 1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 4 import paramiko5 import sys6 import os7 import socket8 import select9 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('\r\n*** EOF\r\n')
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、肆意妄为(二)

 View Code

 1 import paramiko2 import sys3 import os4 import socket5 import select6 import getpass7 import termios8 import tty9 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('\r\n*** EOF\r\n')
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()

 基于Passwd或者RSA进行登陆操作

 1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 import paramiko4 import sys5 import os6 import socket7 import getpass8 import termios9 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('\r\n*** EOF\r\n')
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进行登陆操作

 提示用户选择主机和用户

 1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 import paramiko4 import sys5 import os6 import socket7 import getpass8 import termios9 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('\r\n*** EOF\r\n')
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 python2 # -*- coding:utf-8 -*-3 import paramiko4 import sys5 import os6 import socket7 import getpass8 import termios9 import tty10 import select11 from paramiko.py3compat import u12 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 = False31         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('\r\n*** EOF\r\n')40                         break41                     # 如果用户上一次点击的是tab键,则获取返回的内容写入在记录中42                     if flag:43                         if x.startswith('\r\n'):44                             pass45                         else:46                             temp_list.append(x)47                         flag = False48                     sys.stdout.write(x)49                     sys.stdout.flush()50                 except socket.timeout:51                     pass52             if sys.stdin in r:53                 # 读取用户在终端数据每一个字符54                 x = sys.stdin.read(1)55                 if len(x) == 0:56                     break57                 # 如果用户点击TAB键58                 if x == '\t':59                     flag = True60                 else:61                     # 未点击TAB键,则将每个操作字符记录添加到列表中,以便之后写入文件62                     temp_list.append(x)63 64                 # 如果用户敲回车,则将操作记录写入文件65                 if x == '\r':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 提示用户选择主机和用户(记录操作日志)

http://chatgpt.dhexx.cn/article/Em4pkXk2.shtml

相关文章

python之paramiko模块

paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。 由于使用的是python这样的能够跨平台运行…

Python--paramiko

Paramiko paramiko模块,基于SSH用于连接远程服务器并执行相关操作。 一、安装 1 pip3 install paramiko 二、使用 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: import paramiko# 创建SSH对象 ssh paramiko.SSHClient() # 允…

Python笔记之paramiko模块安装和使用示例

一、paramiko模块简介 paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,基于linux中的ssh服务 。paramiko是第三方模块,需要我们单独安装。通过paramiko模块,我们可以利用python代码程序实现对…

【Python-自动化】paramiko模块

文章目录 运维自动化Python一、模块介绍二、模块应用1.使用paramiko模块,通过ssh协议连接服务器2.解决首次连接known_hosts问题3、执行命令exec_command方法扩展:使用try异常捕获 4、多台服务器执行命令5、从服务器上传下载文件--SFTPClient方法6、多台服…

HttpClient和HtmlUnit的比较总结以及使用技巧(一)

大家在做爬虫、网页采集、通过网页自动写入数据时基本上都接触过这两个组件(权且称之为组件吧),网上入门资料已经很多了,我想从实际的应用角度谈谈我对于这两个组件的看法,并记录在博客中,以便日后翻阅&…

htmlUnit的读取js渲染的页面

htmlUnit的读取js渲染的页面 我这边有个这么的需求,要求前端每次上版本的时候,有一个版本号。然后后端去爬前端,比较禅道的版本发布计划,如果发布计划和生产上的版本号不一致,就告警。 这个跟后端的jar包&#xff0c…

HtmlUnit

HtmlUnit是什么?看下介绍: A java GUI-Less browser, which allows high-level manipulation of web pages, such as filling forms and clicking links; just getPage(url), find a hyperlink, click() and you have all the HTML, JavaScript, and A…

HtmlUnit使用

htmlunit 是一款开源的java 页面分析工具,读取页面后,可以有效的使用htmlunit分析页面上的内容。项目可以模拟浏览器运行,被誉为java浏览器的开源实现。是一个没有界面的浏览器,运行速度迅速。是junit的扩展之一,它采用…

【转】 HtmlUnit简介

HtmlUnit简介: 引自 http://www.javaeye.com/topic/166702 HtmlUnit 是 JUnit 的扩展测试框架之一。HtmlUnit 将返回文档模拟成 HTML,这样您便可以直接处理这些文档了。HtmlUnit 使用例如 table、form 等标识符将测试文档作为 HTML 来处理。它同样需要遵…

HtmlUnit(Java) - 快速入门学习 - 无界面浏览器

文章目录 1. 概述2. 注意2.0 js解析问题2.1 关闭HtmlUnit日志 3. 使用3.1 抓取IT之家周榜内容 - 单页面3.2 抓取IT之家周榜第九篇文章的内容 - 双页面3.3 模拟用户操作 - (这个功能个人感觉非常非常的鸡肋,只能用于非常简单的JS,但是一般网站…

【零基础】快速入门爬虫框架HtmlUnit

迅速的HtmlUnit htmlunit是一款开源的web页面分析工具,理论上来说htmlunit应用于网页的自动化测试,但是相对来说更多人使用它来进行小型爬虫的快速开发。使用htmlunit进行爬虫开发不仅是其运行速度快,更重要的是此框架上手更为容易&#xff0…

保研之路——哈深计算机预推免

哈深计算机预推免 个人情况高校复试参与情况哈工深计算机学院直硕(7.20)结语 嗯!抱着不白花这么多路费住宿费的初衷准备写一个保研经验贴,希望学弟学妹少花点钱吧orz 我的战术大概是只要学校给我发了邀请我就去(除了时…

哈工大计算机学院统一复试划线,哈工大计算机专业,复试比例101%,擦线党没戏了...

原标题:哈工大计算机专业,复试比例101%,擦线党没戏了 这几天哈工大各院系公布了复试线及复试名单,其中「计算机学院」的复试考生比例居然是101%。 哈工大2020年计算机专业的考研复试线为320分(学术学位),以及专业学位的…

【2024考研】哈工大计算机考研854会改成408吗?优缺点分析?怎么复习?哈工大卓越工程师学院点击就送吗?

文章目录 1.哈工大计算机考研专业课的发展历史2.哈工大卓越工程师学院点击就送吗?3.哈工大计算机854会改成408吗?4.哈工大计算机854的优缺点分析4.1 优点4.2 缺点 5.哈工大计算机854怎么复习?5.1 计算机系统(CSAPP)复习指导5.2 计算机网络复习…

【考研】哈尔滨工业大学计算机考研854复习资料

哈尔滨工业大学计算机考研854复习资料 0. 考研初试&复试经验贴1. 初试专业课复习资料资源1.1 复习资料下载1.2 复习资料清单 2. 初试专业课复习资料使用指南2.1 CSAPP资料2.2 数据结构资料2.3 计算机网络资料 更新历史: 2022年4月22日完成初稿2022年5月7日加入…

计算机排名哈工大第三,国内计算机高校排名:哈工大稳坐第2,浙江大学第3,西电第8...

QS世界大学计算机H指数(H指数为混合量化指标,可用于评估研究人员的学术产出量和学术产出水平)前50名中,中国有9所(包括香港大学3所)上榜,前100名中有清华大学、哈工大学、浙江大学等14所世界一流大学建设高校,学校有西安电子科技大…

哈工大深圳计算机就业质量报告,多所高校公布毕业生平均年薪,南京大学和哈工大(深圳)数据亮眼...

原标题:多所高校公布毕业生平均年薪,南京大学和哈工大(深圳)数据亮眼 对于高中学子而言,在将来报考大学时,除了根据自己的兴趣爱好之外,还比较关注对应高校的就业率以及就业质量。毕竟将来大学毕业后还是要走向社会就业的。所以就业后的薪资待遇就成了大家乐意关注的一个点…

哈工大2021秋机器学习期末试题

哈工大2021秋机器学习期末试题 刚刚经历了机器学习复习和考试,这过程简直是太折磨了。 这门课的期末考试往年题还是很有参考价值的。所以我在考试的时候抽了点时间把期末题记了一下,希望能对学弟、学妹(如果有的话)考前复习有所…

哈尔滨工程大学计算机学院保研政策,哈工大保研条件(哈工大2019保研政策)

哈工大保研条件(哈工大2019保研政策) 2020-05-08 10:50:43 共10个回答 去年保研的确实增加了,主要是总校的增加了(40%多),深圳和威海的基本上变化不大,保研率没有超过40%.但是值得特别注意的是,复试中取消了前25%免除笔试的原则.以至于好多总校和威海前25%的同学虽进入复试,却因…

2020哈工大(威海)计算机夏令营面试

2020哈工大威海计算机夏令营面试 6月底收到哈工大(威海)的入营通知,当时我正在参加中南大学的夏令营,因为我校往届也有好多学长学姐保研到哈威,所以入营概率相对较大,也算是我夏令营拿到的为数不多的入营,另外三个分别…