(转)用Python写堡垒机项目

原文:https://blog.csdn.net/ywq935/article/details/78816860

前言
堡垒机是一种运维安全审计系统。主要的功能是对运维人员的运维操作进行审计和权限控制,风险规避。同时堡垒机还有账号集中管理,单点登陆的功能。

堡垒机有以下两个至关重要的功能:
集中管理
安全审计

当公司的服务器变的越来越多后,需要操作这些服务器的人就肯定不只是一个运维人员,同时也可能包括多个开发人员,那么这么多的人操作业务系统,如果权限分配不当就会存在很大的安全风险,举几个场景例子:
设想你们公司有300台Linux服务器,A开发人员需要登录其中5台WEB服务器查看日志或进行问题追踪等事务,同时对另外10台hadoop服务器有root权限,在有300台服务器规模的网络中,按常理来讲你是已经使用了ldap权限统一认证的,你如何使这个开发人员只能以普通用户的身份登录5台web服务器,并且同时允许他以管理员的身份登录另外10台hadoop服务器呢?并且同时他对其它剩下的200多台服务器没有访问权限

小型公司的运维团队为了方面,整个运维团队的运维人员还是共享同一套root密码,这样内部信任机制虽然使大家的工作方便了,但同时存在着极大的安全隐患,很多情况下,一个运维人员只需要管理固定数量的服务器,毕竟公司分为不同的业务线,不同的运维人员管理的业务线也不同,但如果共享一套root密码,其实就等于无限放大了每个运维人员的权限,也就是说,如果某个运维人员想干坏事的话,后果很严重。为了降低风险,于是有人想到,把不同业务线的root密码改掉就ok了么,也就是每个业务线的运维人员只知道自己的密码,这当然是最简单有效的方式,但问题是如果同时用了ldap,这样做又比较麻烦,即使设置了root不通过ldap认证,那新问题就是,每次有运维人员离职,他所在的业务线的密码都需要重新改一次。

因此,堡垒机的诞生就是为了规避这些高风险的问题,同时减少繁琐的重复性工作。

工作流程图:

一、需求分析
1.所有生产服务器配置iptables安全策略,只能通过堡垒机来登陆,用户首先登陆进堡垒机,再通过堡垒机跳转登陆target host.
2.各IT组,按职能划分一个统一的可以真实登陆target host的账户
3.组内的成员,使用自己的账号登陆堡垒机,再使用小组账号登陆target host.
4.审计。记录下各人员的操作记录,出现问题时可以溯源

二、表结构设计
本着最少的字段数据冗余的原则,设计了如下几张表,如果各路大神有更好的设计思路,请指点一二~

表创建代码:

import os,sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from sqlalchemy import Table, Column, Enum,Integer,String, ForeignKey,UniqueConstraint
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from conf import config

Base = declarative_base()

user_m2m_group_bind_host = Table(‘user_m2m_group_bind_host‘, Base.metadata,
Column(‘id‘,Integer,autoincrement=True,primary_key=True),
Column(‘user_id‘, Integer, ForeignKey(‘user.id‘)),
Column(‘group_bind_host_id‘, Integer, ForeignKey(‘group_bind_host.id‘)),
)

user_m2m_group = Table(‘user_m2m_group‘, Base.metadata,
Column(‘user_id‘, Integer, ForeignKey(‘user.id‘)),
Column(‘group_id‘, Integer, ForeignKey(‘group.id‘)),
)

class Host(Base):
__tablename__ = ‘host‘
id = Column(Integer,primary_key=True)
hostname = Column(String(64),unique=True)
ip = Column(String(64),unique=True)
port = Column(Integer,default=22)
groups=relationship(‘Group‘,secondary=‘group_bind_host‘)

def __repr__(self):
return self.hostname

class Group(Base):
__tablename__ = ‘group‘
id = Column(Integer, primary_key=True)
name = Column(String(64), unique=True)
login_passwd=Column(String(64))
bind_hosts = relationship("Host",secondary=‘group_bind_host‘)
users=relationship(‘User‘,secondary=‘user_m2m_group‘)

def __repr__(self):
return self.name

class Group_Bind_Host(Base):
__tablename__ = "group_bind_host"
__table_args__ = (UniqueConstraint(‘group_id‘,‘host_id‘, name=‘_host_remoteuser_uc‘),)
id = Column(Integer, primary_key=True)
group_id = Column(Integer, ForeignKey(‘group.id‘))
host_id = Column(Integer,ForeignKey(‘host.id‘))

users=relationship(‘User‘,secondary=‘user_m2m_group_bind_host‘,backref=‘group_bind_hosts‘)

#host = relationship("Host")
#host_group = relationship("Group",backref="bind_hosts")
#group = relationship("Group")

class User(Base):
__tablename__ = ‘user‘
id = Column(Integer,autoincrement=True,primary_key=True)
username = Column(String(32))
password = Column(String(128))
groups = relationship("Group",secondary="user_m2m_group")
bind_hosts = relationship("Group_Bind_Host", secondary=‘user_m2m_group_bind_host‘)

def __repr__(self):
return self.username

class Log_audit(Base):
__tablename__= ‘log_audit‘
id = Column(Integer,autoincrement=True,primary_key=True)
user_id = Column(Integer)
user_name = Column(String(32))
host_ip = Column(String(32))
login_user = Column(String(32))
action_type = Column(String(16))
cmd=Column(String(128))
date = Column(String(16))

if __name__ == "__main__":
engine=create_engine(config.engine_param)
Base.metadata.create_all(engine) # 创建表结构
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
三、项目代码
1.整体结构:

2.功能说明:
1.管理功能
——表结构初始化创建
——添加组
——添加主机
——添加用户
——添加组-主机绑定

doc目录下提供了几个添加元素的example文档,使用yaml模块解析这些文档,解析为dict数据类型,将解析出的数据添加进数据库内,例如:

对应实现添加user功能的函数:

2.用户视图
——查看属组
—查看属组有权限登陆的主机
——直接输入IP登陆主机
—查看该IP主机是否有可用的有权限的账户可供登陆
——开始会话连接,执行命令时向记录审计日志表添加item

ssh会话实现:
使用了paramiko的demo模块,这个模块本身的交互功能是使用select模型来实现的,使用select监听会话句柄、sys.stdin(标准输入)的可读可写状态,实现字符在终端界面的输入输出。关于I/O多路复用几种模型的个人解读,可以翻看此前的博客:网络编程之I/O模型(以吃牛肉面为例)。
对paramiko交互模块进行修改添加记录功能:当标准输入触发回车键时(代表一个命令输入完毕开始执行),记录下执行人、登陆用户、时间、命令内容,写入数据库。修改后的交互模块代码如下:

# Copyright (C) 2003-2007 Robey Pointer <[email protected]>
#
# This file is part of paramiko.
#
# Paramiko is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Paramiko; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

import socket
import sys
from paramiko.py3compat import u
import datetime
from moudle import table_init
from moudle.db_conn import session

# windows does not have termios...
try:
import termios
import tty
has_termios = True
except ImportError:
has_termios = False

def interactive_shell(chan,user_obj,choose_host,choose_group):
if has_termios:
posix_shell(chan,user_obj,choose_host,choose_group)
else:
windows_shell(chan)

def posix_shell(chan,user_obj,choose_host,choose_group):
import select

oldtty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
cmd = ‘‘

tab_key = False
while True:
r, w, e = select.select([chan, sys.stdin], [], [])
if chan in r:
try:
x = u(chan.recv(1024))
if tab_key:
if x not in (‘\t‘,‘\r\n‘):
#print(‘tab:‘,x)
cmd += x
tab_key = False
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 ‘\r‘ != x:
cmd +=x #输入字符不包含回车,则命令还未输入完成,包含回车且输入字符长度大于0,则记录日志
if ‘\r‘ == x and len(cmd)>0:
log_item = table_init.Log_audit(user_id=user_obj.id,
user_name=user_obj.username,
host_ip=choose_host.ip,
login_user=choose_group.name,
action_type=‘cmd‘,
cmd=cmd ,
date=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

)
session.add(log_item)
session.commit()
cmd = ‘‘

if ‘\t‘ == x:
tab_key = True
# if len(x) == 0:
# break
chan.send(x)

finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

# thanks to Mike Looijmans for this code
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
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
四、运行效果:
在堡垒机上添加用户,在目标主机上添加一个对应登陆用户:
在堡垒机上该用户环境变量配置文件中加入:

/usr/local/python3/bin/python3 /usr/local/packages/MyFortress/bin/user_interface.py
1
使其打开shell后自动运行堡垒机程序,效果如下:

查看数据库审计日志表,记录正常:

写了一个星期,终于能跑起来了,github链接:
https://github.com/yinwenqin/MyFortress-Server
---------------------
作者:ywq935
来源:CSDN
原文:https://blog.csdn.net/ywq935/article/details/78816860?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/liujiacai/p/9792107.html

时间: 2024-12-30 20:47:02

(转)用Python写堡垒机项目的相关文章

基于python的堡垒机

一.堡垒机的概念 堡垒机,也称为跳板机,多用于系统运维环境中.指的是在一个特定的网络环境下,为了保障网络和数据不受来自外部和内部用户的入侵和破坏,而运用各种技术手段实时收集和监控网络环境中每一个组成部分的系统状态.安全事件.网络活动,以便集中报警.及时处理及审计定责. 从功能上分析,它综合了核心系统运维和安全审计管控两大主要功能:从技术实现上分析,它通过切断终端计算机对网络和服务器资源的直接访问,而采用协议代理的方式,接管了终端计算机对网络和服务器的访问.形象地说,终端计算机对目标的访问,均需要

利用Python在堡垒机模式下批量管理后端nginx服务器

在集群环境中,有时候需要批量修改nginx配置,或批量添加vhost主机.手动一个个添加,效率太慢,借助Fabric写了一个批量分发的脚本,会提高不少效率. 思路: (1.在一台nginx修改配置或添加vhost主机,并测试; (2.测试成功后,将配制文件推送至堡垒机(跳板机); (3.在堡垒机上将配置文件分发至其他nginx服务器 [如果原有文件存在,则先备份] ; 只是在堡垒机环境下一个简单的推送文件脚本,比较简陋,代码如下: # -*- coding:utf-8 -*- #! /usr/b

Python之堡垒机

本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多人觉得,堡垒机就是跳板机,其实这个认识是不全面的,跳板功能只是堡垒机所具备的功能属性中的其中一项而已,下面我就给大家介绍一下堡垒机的重要性,以帮助大家参考自己公司的业务是否需要部署堡垒机. 堡垒机有以下两个至关重要的功能: 权限管理 当你公司的服务器变的越来越多后,需要操作这些服务器的人就肯定不只是一个运维人员,同时也可能包括多个开发人员,那么这么多的人

python SQLAlchemy 堡垒机

SQLALchemy ORM db first 数据库操作类 code first 类操作数据库 1.自定义生成表 class 类(base): 列1  列2 根据类去创建表 2.使用类操作表 以后通过类和对象操作数据库 pramiko 堡垒机 ORM 连表 一对多 1.创建表,主动指定外键约束 2.操作 类:repr 单表 连表 session.query(表1).join(表2).all() 多对多 1.创建表,额外的关系表 2.filter() == int_( 都可以是另外一个查询) 3

python之堡垒机(第九天)

本节作业: 通过使用paramiko和sqlalchemy实现堡垒机功能 主要功能实现: 1.用户登录堡垒机后,无需知道密码或密钥可以SSH登录远端服务器: 2.用户对一个组内所有主机批量执行指定命令,获取格式化输出: 3.针对远端主机,可以进行上传下载文件: 4.用户在远端主机上执行的命令,均被记录并入库,实现审计功能: 主要参考了alex的开源代码jumpserver,并添加部分功能. 一.堡垒机具体介绍: 1.堡垒机功能 :        堡垒机,也称为跳板机,多用于系统运维环境中.指的是

源码:自己用Python写的iOS项目自动打包脚本

http://www.cocoachina.com/ios/20160307/15501.html 什么?又要测试包! 做iOS开发几年了,每天除了码代码,改Bug之外,最让我烦恼的莫过于测试的妹子跑过来:“刚才的Bug都改完了吧,再打个包吧”.然而对于这个自己应尽的义务我已经烦透了,先不说要配置各种参数什么的,光是用xcode打包时候clean代码,验证证书就让我焦头烂额,时不时还要翻个墙甚至要手机开个热点才能打包成功.每次打包顺利的话,也要7~8分钟,每天n个包,想早点完成任务准时下班想都别

堡垒机项目实战-批量任务的前端页面开发

onclick="ItmToggle(this)" function ItemToggle(ele) { $(ele).next.toggle() } 隐藏显示切换 JS:trim() 去空格 Ajax另一种方式:$.post("{% url ' ' %}" ,data , function(){ }); python:request.POST.getlist() 获取列表 原文地址:https://www.cnblogs.com/jintian/p/1136693

堡垒机项目实战-web ssh 的使用

linux安装软件一般在usr/local/ 或 /opt/ 原文地址:https://www.cnblogs.com/jintian/p/11349376.html

堡垒机项目实战-批量任务的思路

解耦高则扩展性强 原文地址:https://www.cnblogs.com/jintian/p/11366914.html