Paramiko&堡垒机
Paramiko
paramiko模块,基于SSH用于连接远程服务器并执行相关操作。
一、安装
pip install paramiko
二、使用
SSHClient
用于连接远程服务器并执行基本命令
基于用户名密码连接:
import paramiko # 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='10.0.1.14', port=22, username='root', password='') # 执行命令
stdin, stdout, stderr = ssh.exec_command('ls')
# 获取命令结果
result = stdout.read() # 关闭连接
ssh.close()
用Transport建立一个连接交给SSHClient
import paramiko
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', password='')
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
print stdout.read()
transport.close()
基于公钥密钥连接:
先在本机生成密钥对
一键生成密钥对:
echo -e "\n"|ssh-keygen -t rsa -N ""
ssh-copy-id -i ~/.ssh/id_dsa.pub "-p22 目标服务器账户@目标服务器地址"
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', pkey=private_key)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
# 关闭连接
ssh.close()
用Transport建立一个连接交给SSHClient
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', pkey=private_key)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df')
transport.close()
SFTPClient
用于连接远程服务器并执行上传下载
基于用户名密码上传下载:
import paramiko
transport = paramiko.Transport(('hostname',22))
transport.connect(username='wupeiqi',password='')
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()
基于公钥密钥上传下载:
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
transport = paramiko.Transport(('hostname', 22))
transport.connect(username='wupeiqi', 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()
用paramiko实现执行命令及上传下载
注:文件上传下载只能用transport创建连接,执行命令既可以用Transport建立一个连接交给SSHClient又可以用直接用SSHClient。
所以要既执行命令又上传下载文件就选用Transport
import paramiko
class SSH:
def __init__(self, host,port,user,pwd):
self.host = host
self.port = port
self.user = user
self.pwd = pwd self.transport = None
def connect(self):
self.transport = paramiko.Transport((self.host, self.port,))
self.transport.connect(username=self.user, password=self.pwd) def cmd(self,cmd):
ssh = paramiko.SSHClient()
ssh._transport = self.transport
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read() def download(self,server_path,local_path):
sftp = paramiko.SFTPClient.from_transport(self.transport)
# 将location.py 上传至服务器 /tmp/test.py
# sftp.put('/tmp/location.py', '/tmp/test.py')
# 将remove_path 下载到本地 local_path
sftp.get(server_path, local_path) def upload(self,server_path,local_path):
sftp = paramiko.SFTPClient.from_transport(self.transport)
# 将location.py 上传至服务器 /tmp/test.py
# sftp.put('/tmp/location.py', '/tmp/test.py')
# 将remove_path 下载到本地 local_path
sftp.put(local_path, server_path) def close(self):
self.transport.close() obj = SSH('10.0.1.14',22,'root','')
obj.connect()
# v = obj.cmd('ls')
v = obj.cmd('df')
print(v.decode())
obj.close()
堡垒机

堡垒机执行流程:
- 管理员为用户在服务器上创建账号(将公钥放置服务器,或者使用用户名密码)
- 用户登陆堡垒机,输入堡垒机用户名密码,现实当前用户管理的服务器列表
- 用户选择服务器,并自动登陆
- 执行操作并同时将用户操作记录
注:在服务器用户下的.bashrc设置用户登录后自动执行脚本,如/usr/bin/python /server/scripts/menu.py
实现过程
一:
import paramiko
import sys
import os
import socket
import select
import getpass tran = paramiko.Transport(('10.0.1.14', 22,))
tran.start_client()
tran.auth_password('root', '') # 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell() #########
# 利用sys.stdin,肆意妄为执行操作
# 用户在终端输入内容,并将内容发送至远程服务器
# 远程服务器执行命令,并将结果返回
# 用户终端显示内容
######### chan.close()
tran.close()
二:
import paramiko
import sys
import os
import socket
import select
import getpass
from paramiko.py3compat import u tran = paramiko.Transport(('10.0.1.14', 22,))
tran.start_client()
tran.auth_password('root', '') # 打开一个通道
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()
三:
import paramiko
import sys
import os
import socket
import select
import getpass
from paramiko.py3compat import u 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() 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()
上面的代码存在缺陷:不能TAB补全命令,所以继续优化,改变tty属性,设置为每输入一个字符就向服务器端发送一个字符,
退出终端后将tty属性
四:
import paramiko
import sys
import os
import socket
import select
import getpass
import termios
import tty
from paramiko.py3compat import u tran = paramiko.Transport(('10.211.55.4', 22,))
tran.start_client()
tran.auth_password('wupeiqi', '') # 打开一个通道
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()
为上面优化过的代码加入登录功能。
import paramiko
import sys
import os
import socket
import getpass
import termios
import tty
import select
from paramiko.py3compat import u def interactive_shell(chan):
# 获取原tty属性
oldtty = termios.tcgetattr(sys.stdin)
try:
# 为tty设置新属性
# 默认当前tty设备属性:
# 输入一行回车,执行
# CTRL+C 进程退出,遇到特殊字符,特殊处理。 # 这是为原始模式,不认识所有特殊符号
# 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
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
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) def run():
hostname = input('请输入主机名: ')
tran = paramiko.Transport((hostname, 22,))
tran.start_client() username = input('请输入用户名: ')
auth = input('请输入密码进行验证(p) 或 (r)sa Key进行验证?')
if auth == 'r':
path = input('请输入RSA key 路径: ')
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('请输入密码 %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()
为上面的代码加入选择主机以及选择用户的功能
import paramiko
import sys
import os
import socket
import getpass
import termios
import tty
import select
from paramiko.py3compat import u def interactive_shell(chan):
# 获取原tty属性
oldtty = termios.tcgetattr(sys.stdin)
try:
# 为tty设置新属性
# 默认当前tty设备属性:
# 输入一行回车,执行
# CTRL+C 进程退出,遇到特殊字符,特殊处理。 # 这是为原始模式,不认识所有特殊符号
# 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
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
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) def run():
db_dict = {
'c1.salt.com': {
'root': {'user': 'root', 'auth': 'r', "cert": 'key路径'},
'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
},
'c2.salt.com': {
'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
}, } for row in db_dict.keys():
print(row) hostname = input('请选择主机: ')
tran = paramiko.Transport((hostname, 22,))
tran.start_client() for item in db_dict[hostname].keys():
print(item) username = input('请输入用户: ') user_dict = db_dict[hostname][username]
if username['auth'] == 'r':
key = paramiko.RSAKey.from_private_key_file(user_dict['cert'])
tran.auth_publickey(username, key)
else:
pw = user_dict['cert']
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()
为上面的代码加入选择记录日志的功能
import paramiko
import sys
import os
import socket
import getpass
import termios
import tty
import select
from paramiko.py3compat import u def interactive_shell(chan):
# 获取原tty属性
oldtty = termios.tcgetattr(sys.stdin)
try:
# 为tty设置新属性
# 默认当前tty设备属性:
# 输入一行回车,执行
# CTRL+C 进程退出,遇到特殊字符,特殊处理。 # 这是为原始模式,不认识所有特殊符号
# 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
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
# 如果用户上一次点击的是tab键,则获取返回的内容写入在记录中
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)
if len(x) == 0:
break
# 如果用户点击TAB键
if x == '\t':
flag = True
else:
# 未点击TAB键,则将每个操作字符记录添加到列表中,以便之后写入文件
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 run():
db_dict = {
'c1.salt.com': {
'root': {'user': 'root', 'auth': 'r', "cert": 'key路径'},
'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
},
'c2.salt.com': {
'root': {'user': 'root', 'auth': 'r', "cert": 'key路径'},
'alex': {'user': 'alex', 'auth': 'p', "cert": '密码'},
}, } for row in db_dict.keys():
print(row) hostname = input('请选择主机: ')
tran = paramiko.Transport((hostname, 22,))
tran.start_client() for item in db_dict[hostname].keys():
print(item) username = input('请输入用户: ') user_dict = db_dict[hostname][username]
if username['auth'] == 'r':
key = paramiko.RSAKey.from_private_key_file(user_dict['cert'])
tran.auth_publickey(username, key)
else:
pw = user_dict['cert']
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()
Paramiko&堡垒机的更多相关文章
- paramiko堡垒机、线程及锁
1.使用paramiko实现ssh连接和scp拷贝 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 1.1 SSHClient 用于连接远 ...
- paramiko 堡垒机
用paramiko写堡垒机 paramiko paramiko模块,基于SSH用于连接远程服务器并执行相关操作. 基本用法 SSHClient 基于用户名密码连接: 基础用法: import para ...
- python远程连接paramiko 模块和堡垒机实现
paramiko使用 paramiko模块是基于python实现了SSH2远程安全连接,支持认证和密钥方式,可以实现远程连接.命令执行.文件传输.中间SSH代理功能 安装 pip install pa ...
- 利用paramiko模块实现堡垒机+审计功能
paramiko模块是一个远程连接服务器,全真模拟ssh2协议的python模块,借助paramiko源码包中的demos目录下:demo.py和interactive.py两个模块实现简单的堡垒机+ ...
- python之实现基于paramiko和mysql数据库的堡垒机
一.堡垒机结构 堡垒机执行流程: 管理员为用户在服务器上创建账号(将公钥放置服务器,或者使用用户名密码) 用户登陆堡垒机,输入堡垒机用户名密码,现实当前用户管理的服务器列表 用户选择服务器,并自动登陆 ...
- Pyhton开发堡垒机之paramiko模块
堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: + ...
- paramiko模块实现堡垒机
通过SSHClient 执行命令 """通过用户名密码验证""" import paramiko # 创建 SSH 对象 ssh = par ...
- Python自动化运维之19、Paramiko模块和堡垒机实战
paramiko模块 paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实 ...
- 堡垒机--paramiko模块
做堡垒机之前,来了解一下paramiko模块. 实际上底层封装的SSH. SSHclient(1) import paramiko #实例化一个ssh ssh = paramiko.SSHClient ...
随机推荐
- s21day05 python笔记
s21day05 python笔记 一.昨日内容回顾及补充 回顾 补充 列表独有功能 extend:循环添加到一个列表中 1.users = ['张三',66],people = ['王五',99] ...
- day 023-python 包
包 : 我 们创建的每个文件夹都可以被称之为包. 但是我们要注意, 在python2中规定.中包内必须存在 __init__.py文件. python3可有可无,但一般要求写上.创建包的目的不是为了 ...
- 洛谷 P1164:小A点菜(DP/DFS)
题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家--餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:"随便点". 题目描述 不过ui ...
- (8)Python连接操作MySQL
pymysql模块下的方法 '''必须实例化对象才能建立连接''' 1.pymysql.connect #和MySQL建立连接 '''得由对象去调用定义游标''' 2.xxx.sursor() # ...
- YIT-CTF—Web
一:背后 打开传送门——>查看网页源代码——>1b0679be72ad976ad5d491ad57a5eec0——>用MD5解密 二:一种编码 [][(![]+[])[+[]]+([ ...
- Go Example--通道方向
package main import "fmt" func main() { pings := make(chan string, 1) pongs := make(chan s ...
- zabbix监控mysql最简单的方法
该实验基于我的上一篇文章监控第一台主机的基础上 首先,因为水平有限,我选择直接关闭了防火墙和SELinux. 环境: 两台centos7,服务器端IP是192.168.200.128(以下简称主机), ...
- sqler sql 转rest api 防止sql 注入
sqler 对于sql Sanitization 的处理,我们可以使用bind 指令 说明: 这个是2.0 的功能,注意版本的使用 参考格式 addpost { // $input is a ...
- 寻找“最好”(4)——不等约束和KKT条件
不等约束 上篇文章介绍了如何在等式约束下使用拉格朗日乘子法,然而真实的世界哪有那么多等式约束?我们碰到的大多数问题都是不等约束.对于不等约束的优化问题,可以这样描述: 其中f(x)是目标函数,g(x) ...
- 如何优化JavaScript的构造函数
首先看一个构造函数User,我们在调用User创建一个实例的的时候,一般都是要写上new操作符的.在这里说明一下,如果使用new关键字调用构造函数,那么构造函数里面的this总是是指向一个全新的对象( ...