Python自动化开发学习13-堡垒机开发

简介:

堡垒机介绍

很多人觉得,堡垒机就是跳板机,这是不全面的。跳板功能只是堡垒机所具备的功能的其中一项。堡垒机还有以下两个至关重要的功能:

  • 权限管理 : 用户使用堡垒机账号登录堡垒机系统。不需要知道别的主机的账号和密码,都是由堡垒机系统管理的。用户可以登录的主机和每台主机上所拥有的权限也是由堡垒机系统管理的。
  • 审计管理 : 用户的所有操作都是在堡垒机上执行的,所以都会被记录保存。其实对于操作的结果(就是屏幕上打印的结果),如果需要也是可以记录保存的。不过一般不那么做,而且数据量也会有点大。

开源堡垒机项目

号称没有好的开源项目,因为底层的SSH还是通过paramiko模块的长链接的ssh实现的。但是这个和原生的ssh比还是不太稳定,不太好用。不适合生产环境。要好用还是得去改原生的ssh,但是我们不会,我们只会改python。总之这章就是实现一个堡垒机的功能,真要做个好用的以后再说吧。
比较有名的大概是这个:jumpserver - 开源跳板机

paramiko模块的长连接

虽然上面说了,用这个模块不稳定,但是我们也没办法,毕竟只会这个。
paramiko之前已经学习过了,不过当时用的都是短连接。即:连接一次,执行一条命令,返回结果,断开。这里我们要用长连接。
长连接的代码在demos文件夹下的demo.py这个文件里,另外还要用到interactive.py这个文件。安装模块的时候不安装这个demos文件夹,所以我们去github上下下来:
https://github.com/paramiko/paramiko/tree/master/demos
利用demo.py程序,我们可以进行ssh的长连接。下面的开发都是基于这个程序为基础,在这个程序的基础上,修改该程序的源码添加上记录用户输入的代码,并写入数据库。于是审计管理便实现了。

堡垒机构架

任何人只能通过堡垒机登录设备,堡垒机可以链接管理所有的设备:
Python自动化开发学习13-堡垒机开发

配置环境变量

还需要确保用户一登录堡垒机就进入你的程序,并且不能退出(一退出就退出整个堡垒机),就是只能在你的做的shell下运行,不能进入原生的shell。可以通过设置环境变量实现:
环境变量保存在这里: ~/.bashrc,修改文件在最后加上这句: python3 /etc/myJunpServer.py 直接运行你的程序。首次设置完成后如果要让它立刻生效,可以执行这个命令:source .bashrc 加载最新的配置。

表结构设计

主机表:

id 主机名 端口号 注释
自增id IP或域名 数值类型,默认22 注释信息

主机认证表:

id 名称 用户名 密码 注释
自增id 唯一约束 用户名 明文的字符串 注释信息

主机认证绑定表(分别和主机表以及主机认证表建立一对一关联):

这张就是主机表和主机认证表的多对多关联的结合表,原本不需要单独建立的。但是这张表多加了一个自增id,id还需要去分别和账号表以及群组表建立多对多关联。总之,这样操作是可以实现的,也没有或者说不会3张表之间建立多对多关联的方法,实际试了一下也确实没实现,暂时只会这么搞。
主机id 和 认证id 要做联合唯一

id 主机id 认证id
自增id 关联主机表的id 关联主机认证表的id

主机群组表(和主机认证绑定表多对多关联,和账号表多对多关联):

不同的群组里可能包含相同的机器,但是不同群组中同一台机器对应的权限可能不同。所以这里直接关联主机与认证的一条绑定关系。

id 群组名 备注
自增id 唯一 备注信息

堡垒机账号表(和主机认证绑定表多对多关联,和主机群组表多对多关联):

id 用户名 密码
自增id 唯一约束 加密存储

审计日志记录表:

通过绑定表的id,可以查询到关联的主机和关联的认证信息

id 时间 用户id 绑定表id 操作消息
自增id 操作时间 关联账号表的id 关联绑定表的id 操作内容

创建表结构的代码如下:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Enum, DateTime
from sqlalchemy import ForeignKey, Table, UniqueConstraint
from sqlalchemy.orm import relationship

engine = create_engine("mysql+pymysql://admin:admin123@192.168.3.103/week12",
                                       encoding='utf-8', echo=True)
Base = declarative_base()

group_to_bind = Table('group_to_bind', Base.metadata,
                      Column('group_id', Integer, ForeignKey('host_group.id')),
                      Column('bind_host_id', Integer, ForeignKey('bind_host.id')),
                      )  # 主机群组和绑定表的结合表

user_to_bind = Table('user_to_bind', Base.metadata,
                     Column('user_id', Integer, ForeignKey('user.id')),
                     Column('bind_host_id', Integer, ForeignKey('bind_host.id')),
                     )  # 用户和绑定表的结合表

user_to_group = Table('user_to_group', Base.metadata,
                      Column('user_id', Integer, ForeignKey('user.id')),
                      Column('group_id', Integer, ForeignKey('host_group.id'))
                      )  # 用户和群组的结合表

class Host(Base):
    """主机表
    主机名:联合唯一,IP地址或域名
    端口号:联合唯一,默认22
    注释:
    """
    __tablename__ = 'host'
    id = Column(Integer, primary_key=True)
    hostname = Column(String(32), nullable=False)
    port = Column(Integer, server_default='22')
    description = Column(String(32))
    __table_args__ = (UniqueConstraint('hostname', 'port', name='hostname_port'),)

class Authentication(Base):
    """认证表
    用户名:
    密码:明文的设备密码
    注释:
    """
    __tablename__ = 'authentication'
    id = Column(Integer, primary_key=True)
    authname = Column(String(32), nullable=False, unique=True)
    username = Column(String(32), nullable=False)
    password = Column(String(32), nullable=False)
    description = Column(String(32))

class BindHost(Base):
    """主机和认证绑定表
    分别和主机id 以及 认证id 联立一对一关联
    主机id 和 认证id 要做联合唯一
    """
    __tablename__ = 'bind_host'
    id = Column(Integer, primary_key=True)
    host_id = Column(Integer, ForeignKey('host.id'))
    auth_id = Column(Integer, ForeignKey('authentication.id'))
    __table_args__ = (UniqueConstraint('host_id', 'auth_id', name='host_auth'),)
    host = relationship('Host', backref='bind_host')
    auth = relationship('Authentication', backref='bind_host')

class HostGroup(Base):
    """主机群组表
    群组名:唯一
    注释:
    """
    __tablename__ = 'host_group'
    id = Column(Integer, primary_key=True)
    groupname = Column(String(32), nullable=False, unique=True)
    description = Column(String(32))
    bind_host = relationship('BindHost', secondary=group_to_bind, backref='host_group')

class User(Base):
    """用户账号表
    用户名:不唯一
    密码:sha256的hexdigest(),需要64位
    """
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    username = Column(String(32), nullable=False, unique=True)
    password = Column(String(64), nullable=False)
    host_group = relationship('HostGroup', secondary=user_to_group, backref='user')
    bind_host = relationship('BindHost', secondary=user_to_bind, backref='user')

class Audit(Base):
    """审计日志表"""
    __tablename__ = 'audit'
    id = Column(Integer, primary_key=True)
    time = Column(DateTime)
    user_id = Column(Integer, ForeignKey('user.id'))
    bind_id = Column(Integer, ForeignKey('bind_host.id'))
    msg = Column(String(255))
    user = relationship('User', backref='audit')
    bind_host = relationship('BindHost', backref='audit')

Base.metadata.create_all(engine)  # 创建所有表结构

__all__ = ['Host',
           'Authentication',
           'BindHost',
           'HostGroup',
           'User',
           'Audit'
           ]











本文转自骑士救兵51CTO博客,原文链接:http://blog.51cto.com/steed/2066244,如需转载请自行联系原作者
相关文章
|
6月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
392 1
|
6月前
|
存储 Java 数据处理
(numpy)Python做数据处理必备框架!(一):认识numpy;从概念层面开始学习ndarray数组:形状、数组转置、数值范围、矩阵...
Numpy是什么? numpy是Python中科学计算的基础包。 它是一个Python库,提供多维数组对象、各种派生对象(例如掩码数组和矩阵)以及用于对数组进行快速操作的各种方法,包括数学、逻辑、形状操作、排序、选择、I/0 、离散傅里叶变换、基本线性代数、基本统计运算、随机模拟等等。 Numpy能做什么? numpy的部分功能如下: ndarray,一个具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组 用于对整组数据进行快速运算的标准数学函数(无需编写循环)。 用于读写磁盘数据的工具以及用于操作内存映射文件的工具。 线性代数、随机数生成以及傅里叶变换功能。 用于集成由C、C++
529 1
|
6月前
|
算法 Java Docker
(Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
IF 条件判断 使用if语句,对条件进行判断 true则执行代码块缩进语句 false则不执行代码块缩进语句,如果有else 或 elif 则进入相应的规则中执行
967 1
|
6月前
|
存储 Java 索引
(Python基础)新时代语言!一起学习Python吧!(二):字符编码由来;Python字符串、字符串格式化;list集合和tuple元组区别
字符编码 我们要清楚,计算机最开始的表达都是由二进制而来 我们要想通过二进制来表示我们熟知的字符看看以下的变化 例如: 1 的二进制编码为 0000 0001 我们通过A这个字符,让其在计算机内部存储(现如今,A 字符在地址通常表示为65) 现在拿A举例: 在计算机内部 A字符,它本身表示为 65这个数,在计算机底层会转为二进制码 也意味着A字符在底层表示为 1000001 通过这样的字符表示进行转换,逐步发展为拥有127个字符的编码存储到计算机中,这个编码表也被称为ASCII编码。 但随时代变迁,ASCII编码逐渐暴露短板,全球有上百种语言,光是ASCII编码并不能够满足需求
268 4
|
7月前
|
JavaScript Java 大数据
基于python的网络课程在线学习交流系统
本研究聚焦网络课程在线学习交流系统,从社会、技术、教育三方面探讨其发展背景与意义。系统借助Java、Spring Boot、MySQL、Vue等技术实现,融合云计算、大数据与人工智能,推动教育公平与教学模式创新,具有重要理论价值与实践意义。
|
9月前
|
监控 数据安全/隐私保护 Python
微信自动抢红包免费版,2025微信抢红包神器,微信红包挂苹果版【python仅供学习】
这个模拟项目包含5个模块:核心监控逻辑、用户界面、配置管理、实用工具和主程序入口
|
6月前
|
数据采集 运维 监控
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
本文系统解析爬虫与自动化核心技术,涵盖HTTP请求、数据解析、分布式架构及反爬策略,结合Scrapy、Selenium等框架实战,助力构建高效、稳定、合规的数据采集系统。
1030 62
爬虫与自动化技术深度解析:从数据采集到智能运维的完整实战指南
|
7月前
|
运维 Linux 网络安全
自动化真能省钱?聊聊运维自动化如何帮企业优化IT成本
自动化真能省钱?聊聊运维自动化如何帮企业优化IT成本
223 4

推荐镜像

更多