Python----Paramiko模块和堡垒机实战
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。其实它的底层是对ssh的上层代码的一个封装
一、下载安装
1
2
3
|
#pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto tomcat@node:~$ pip install pycrypto tomcat@node:~$ pip install paramiko |
二、模块使用
1、SSHClient 用于连接远程服务器并执行基本命令
(1)基于用户名密码连接两种方式:
-->第一种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname = '192.168.1.21' , port = 22 , username = 'root' , password = '123456' ) # 执行命令 stdin, stdout, stderr = ssh.exec_command( 'ls' ) # 获取命令结果 result = stdout.read() # 关闭连接 ssh.close() |
-->二种:SSHClient 封装 Transport
1
2
3
4
5
6
7
8
9
10
11
12
|
import paramiko transport = paramiko.Transport(( '192.168.1.21' , 22 )) transport.connect(username = 'root' , password = '123456' ) ssh = paramiko.SSHClient() ssh._transport = transport stdin, stdout, stderr = ssh.exec_command( 'df' ) print stdout.read() transport.close() |
(2)基于公钥密钥连接的两种方式:
-->第一种
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import paramiko private_key = paramiko.RSAKey.from_private_key_file( '/root/.ssh/id_rsa' ) # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname = '192.168.1.21' , port = 22 , username = 'root' , key = private_key) # 执行命令 stdin, stdout, stderr = ssh.exec_command( 'df' ) # 获取命令结果 result = stdout.read() # 关闭连接 ssh.close() |
-->第二种:SSHClient 封装 Transport
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import paramiko private_key = paramiko.RSAKey.from_private_key_file( '/root/.ssh/id_rsa' ) transport = paramiko.Transport(( '192.168.1.21' , 22 )) transport.connect(username = 'root' , pkey = private_key) ssh = paramiko.SSHClient() ssh._transport = transport stdin, stdout, stderr = ssh.exec_command( 'df' ) transport.close() |
2、SFTPClient用于连接远程服务器并执行上传下载
(1)基于用户名密码上传下载:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import paramiko transport = paramiko.Transport(( '192.168.1.21' , 22 )) transport.connect(username = 'root' ,password = '123456' ) sftp = paramiko.SFTPClient.from_transport(transport) # 将location.py 上传至服务器 /tmp/test.py sftp.put( '/tmp/location.py' , '/tmp/test.py' ) # 将remove_path 下载到本地 local_path sftp.get( 'remove_path' , 'local_path' ) transport.close() |
(2)基于公钥密钥上传下载:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import paramiko private_key = paramiko.RSAKey.from_private_key_file( '/root/.ssh/id_rsa' ) transport = paramiko.Transport(( '192.168.1.21' , 22 )) transport.connect(username = 'root' , pkey = private_key ) sftp = paramiko.SFTPClient.from_transport(transport) # 将location.py 上传至服务器 /tmp/test.py sftp.put( '/tmp/location.py' , '/tmp/test.py' ) # 将remove_path 下载到本地 local_path sftp.get( 'remove_path' , 'local_path' ) transport.close() |
3、实例:通过transport实现远程执行命令和上传文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#!/usr/bin/env python # -*- coding:utf-8 -*- import paramiko class SSHConnection( object ): def __init__( self , host = '192.168.1.21' , port = 22 , username = 'root' ,pwd = '123456' ): self .host = host self .port = port self .username = username self .pwd = pwd self .__k = None def run( self ): self .connect() pass self .close() def connect( self ): transport = paramiko.Transport(( self .host, self .port)) transport.connect(username = self .username,password = self .pwd) self .__transport = transport def close( self ): self .__transport.close() def cmd( self , command): ssh = paramiko.SSHClient() ssh._transport = self .__transport # 执行命令 stdin, stdout, stderr = ssh.exec_command(command) # 获取命令结果 result = stdout.read() return result def upload( self ,local_path, target_path): # 连接,上传 sftp = paramiko.SFTPClient.from_transport( self .__transport) # 将location.py 上传至服务器 /tmp/test.py sftp.put(local_path, target_path) ssh = SSHConnection() ssh.connect() r1 = ssh.cmd( 'df' ) print (r1.decode()) #ssh.upload('test.py', "/root/test.py") ssh.upload( 's13_par.py' , "/root/s7.py" ) ssh.close() |
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
import uuid class SSHConnection(object): def __init__(self, host='172.16.103.191', port=22, username='wupeiqi',pwd='123'):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.__k = None def create_file(self):
file_name = str(uuid.uuid4())
with open(file_name,'w') as f:
f.write('sb')
return file_name def run(self):
self.connect()
self.upload('/home/wupeiqi/tttttttttttt.py')
self.rename('/home/wupeiqi/tttttttttttt.py', '/home/wupeiqi/ooooooooo.py)
self.close() def connect(self):
transport = paramiko.Transport((self.host,self.port))
transport.connect(username=self.username,password=self.pwd)
self.__transport = transport def close(self): self.__transport.close() def upload(self,target_path):
# 连接,上传
file_name = self.create_file() sftp = paramiko.SFTPClient.from_transport(self.__transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(file_name, target_path) def rename(self, old_path, new_path): ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 执行命令
cmd = "mv %s %s" % (old_path, new_path,)
stdin, stdout, stderr = ssh.exec_command(cmd)
# 获取命令结果
result = stdout.read() def cmd(self, command):
ssh = paramiko.SSHClient()
ssh._transport = self.__transport
# 执行命令
stdin, stdout, stderr = ssh.exec_command(command)
# 获取命令结果
result = stdout.read()
return result ha = SSHConnection()
ha.run()
1
2
3
4
5
6
|
# 对于更多限制命令,需要在系统中设置 / etc / sudoers Defaults requiretty Defaults:cmdb !requiretty Demo |
堡垒机
堡垒机执行流程:
- 管理员为用户在服务器上创建账号(将公钥放置服务器,或者使用用户名密码)
- 用户登陆堡垒机,输入堡垒机用户名密码,现实当前用户管理的服务器列表
- 用户选择服务器,并自动登陆
- 执行操作并同时将用户操作记录
注:配置.brashrc实现ssh登陆后自动执行脚本,如:/usr/bin/python /home/wupeiqi/menu.py
实现过程(前戏)
# 利用sys.stdin,肆意妄为执行操作
# 用户在终端输入内容,并将内容发送至远程服务器
# 远程服务器执行命令,并将结果返回
# 用户终端显示内容
版本一:能连上远程服务器在终端任意输入命令,但无法做到tab键补全命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
import paramiko import sys import os import socket import select import getpass from paramiko.py3compat import u tran = paramiko.Transport(( '192.168.1.21' , 22 ,)) tran.start_client() tran.auth_password( 'root' , '123456' ) # 打开一个通道 chan = tran.open_session() # 获取一个终端 chan.get_pty() # 激活器 chan.invoke_shell() while True : # 监视用户输入和服务器返回数据 # sys.stdin 处理用户输入 # chan 是之前创建的通道,用于接收服务器返回信息 readable, writeable, error = select.select([chan, sys.stdin, ],[],[], 1 ) if chan in readable: try : x = u(chan.recv( 1024 )) if len (x) = = 0 : print ( '\r\n*** EOF\r\n' ) break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in readable: inp = sys.stdin.readline() chan.sendall(inp) chan.close() tran.close() |
版本二:在版本一上增加了命令补全功能和命令记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
import paramiko import sys import os import socket import select import getpass import termios import tty from paramiko.py3compat import u tran = paramiko.Transport(( '192.168.1.21' , 22 ,)) tran.start_client() tran.auth_password( 'root' , '123456' ) # 打开一个通道 chan = tran.open_session() # 获取一个终端 chan.get_pty() # 激活器 chan.invoke_shell() # 获取原tty属性 oldtty = termios.tcgetattr(sys.stdin) try : # 为tty设置新属性 # 默认当前tty设备属性: # 输入一行回车,执行 # CTRL+C 进程退出,遇到特殊字符,特殊处理。 # 这是为原始模式,不认识所有特殊符号 # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器 tty.setraw(sys.stdin.fileno()) chan.settimeout( 0.0 ) while True : # 监视 用户输入 和 远程服务器返回数据(socket) # 阻塞,直到句柄可读 r, w, e = select.select([chan, sys.stdin], [], [], 1 ) if chan in r: try : x = u(chan.recv( 1024 )) if len (x) = = 0 : print ( '\r\n*** EOF\r\n' ) break sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read( 1 ) if len (x) = = 0 : break chan.send(x) finally : # 重新设置终端属性 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) chan.close() tran.close() |
版本三:windows、linux通用版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
import paramiko import sys import os import socket import getpass from paramiko.py3compat import u # windows does not have termios... try : import termios import tty has_termios = True except ImportError: has_termios = False def interactive_shell(chan): if has_termios: posix_shell(chan) else : windows_shell(chan) def posix_shell(chan): import select oldtty = termios.tcgetattr(sys.stdin) try : tty.setraw(sys.stdin.fileno()) tty.setcbreak(sys.stdin.fileno()) chan.settimeout( 0.0 ) log = open ( 'handle.log' , 'a+' , encoding = 'utf-8' ) flag = False temp_list = [] while True : r, w, e = select.select([chan, sys.stdin], [], []) if chan in r: try : x = u(chan.recv( 1024 )) if len (x) = = 0 : sys.stdout.write( '\r\n*** EOF\r\n' ) break if flag: if x.startswith( '\r\n' ): pass else : temp_list.append(x) flag = False sys.stdout.write(x) sys.stdout.flush() except socket.timeout: pass if sys.stdin in r: x = sys.stdin.read( 1 ) import json if len (x) = = 0 : break if x = = '\t' : flag = True else : temp_list.append(x) if x = = '\r' : log.write(''.join(temp_list)) log.flush() temp_list.clear() chan.send(x) finally : termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) def windows_shell(chan): import threading sys.stdout.write( "Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n" ) def writeall(sock): while True : data = sock.recv( 256 ) if not data: sys.stdout.write( '\r\n*** EOF ***\r\n\r\n' ) sys.stdout.flush() break sys.stdout.write(data) sys.stdout.flush() writer = threading.Thread(target = writeall, args = (chan,)) writer.start() try : while True : d = sys.stdin.read( 1 ) if not d: break chan.send(d) except EOFError: # user hit ^Z or F6 pass def run(): default_username = getpass.getuser() username = input ( 'Username [%s]: ' % default_username) if len (username) = = 0 : username = default_username hostname = input ( 'Hostname: ' ) if len (hostname) = = 0 : print ( '*** Hostname required.' ) sys.exit( 1 ) tran = paramiko.Transport((hostname, 22 ,)) tran.start_client() default_auth = "p" auth = input ( 'Auth by (p)assword or (r)sa key[%s] ' % default_auth) if len (auth) = = 0 : auth = default_auth if auth = = 'r' : default_path = os.path.join(os.environ[ 'HOME' ], '.ssh' , 'id_rsa' ) path = input ( 'RSA key [%s]: ' % default_path) if len (path) = = 0 : path = default_path try : key = paramiko.RSAKey.from_private_key_file(path) except paramiko.PasswordRequiredException: password = getpass.getpass( 'RSA key password: ' ) key = paramiko.RSAKey.from_private_key_file(path, password) tran.auth_publickey(username, key) else : pw = getpass.getpass( 'Password for %s@%s: ' % (username, hostname)) tran.auth_password(username, pw) # 打开一个通道 chan = tran.open_session() # 获取一个终端 chan.get_pty() # 激活器 chan.invoke_shell() interactive_shell(chan) chan.close() tran.close() if __name__ = = '__main__' : run() |
更多参见:paramoko源码 https://github.com/paramiko/paramiko
Alex堡垒机:http://www.cnblogs.com/alex3714/articles/5286889.html
Python----Paramiko模块和堡垒机实战的更多相关文章
- Python自动化运维之19、Paramiko模块和堡垒机实战
paramiko模块 paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实 ...
- python远程连接paramiko 模块和堡垒机实现
paramiko使用 paramiko模块是基于python实现了SSH2远程安全连接,支持认证和密钥方式,可以实现远程连接.命令执行.文件传输.中间SSH代理功能 安装 pip install pa ...
- 利用paramiko模块实现堡垒机+审计功能
paramiko模块是一个远程连接服务器,全真模拟ssh2协议的python模块,借助paramiko源码包中的demos目录下:demo.py和interactive.py两个模块实现简单的堡垒机+ ...
- paramiko模块实现堡垒机
通过SSHClient 执行命令 """通过用户名密码验证""" import paramiko # 创建 SSH 对象 ssh = par ...
- Python Paramiko模块与MySQL数据库操作
Paramiko模块批量管理:通过调用ssh协议进行远程机器的批量命令执行. 要使用paramiko模块那就必须先安装这个第三方模块,仅需要在本地上安装相应的软件(python以及PyCrypto), ...
- python paramiko模块学习分享
python paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Sola ...
- Python 13 简单项目-堡垒机
本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功 ...
- Python之路:堡垒机实例
堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: 1 ...
- Python之路:堡垒机实例以及数据库操作
一.堡垒机前戏 开发堡垒机之前,先学习Python的paramiko模块,该模块基于SSH用于连接远程服务器并执行相关操作. SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: ...
随机推荐
- Linux系统——文件系统与LVM 逻辑
格式化命令 mkfs. mkswap mkfs格式化数据磁盘 # mkfs -t ext4 /dev/sdb1 # mkfs.ext4 /dev/sdb1 -t 指定格式化文件类型 -b 指定bloc ...
- Springboot 日志管理配置logback-spring.xml
几种常见的日志 Log4j:是最早的日志框架,是apach旗下的,可以单独使用,也可配合日志框架JCL使用: Log4j2:apach旗下的关于log4j的升级版: Logback:是基于slf4j接 ...
- RPC细节
服务化有什么好处? 服务化的一个好处就是,不限定服务的提供方使用什么技术选型,能够实现大公司跨团队的技术解耦,如下图所示: 服务A:欧洲团队维护,技术背景是Java 服务B:美洲团队维护,用C++实现 ...
- DataTables VS EasyUI DataGrid 基础应用 转
DataTables中文网推出了 第一篇 关于DataTables和其他表格插件比较后,为了把让这个比较更有意义,更能帮助到大家,DataTables中文网 做了问卷调查,根据小伙伴们的填写我归纳了一 ...
- 对Spring Ioc 以及DI的精彩理解
转:http://blog.csdn.net/cyjs1988/article/details/50352916 学习过spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注 ...
- jQuery height() 需要注意的地方
var aNode = $('#id'); var height = aNode.height(); //如果在获取height前,aNode已经是display:none 或者说 aNode是隐藏的 ...
- Thinkphp5.0实战开发一------命名空间详解
序言 ThinkPHP是一个快速.兼容而且简单的轻量级国产PHP开发框架,使用ThinkPHP框架可以极大简化我们的开发过程,节省时间.这个专题我将记录自己学习使用ThinkPHP5.0的进行实战开发 ...
- 20145310 《Java程序设计》第4周学习总结
20145310 <Java程序设计>第4周学习总结 教材学习内容总结 本周主要进行第五章和第六章的学习. 第六章 继承与多态 子类(Inherit)继承父类,避免重复的行为定义,不过并非 ...
- MR案例:Map-Join
适用场景:一张表十分小[key不可重复].一张表非常大. 用法:在Job提交时,首先将小表加载到 DistributedCache 分布式缓存中,然后从DistributeCache中读取小表解析成 ...
- Hive架构
Hive组织数据包含四种层次:DataBase --> Table --> Partition --> Bucket,对应在HDFS上都是文件夹形式. 数据库和数据仓库的区别: 1) ...