一、作业需求:
1.业务需求
兼顾业务安全目标与用户体验,堡垒机部署后,不应使用户访问业务系统的访问变的复杂,否则工作将很难推进,因为没人喜欢改变现状,尤其是改变后生活变得更艰难
保证堡垒机稳定安全运行, 没有100%的把握,不要上线任何新系统,即使有100%把握,也要做好最坏的打算,想好故障预案
2.功能需求
所有的用户操作日志要保留在数据库中
每个用户登录堡垒机后,只需要选择具体要访问的设置,就连接上了,不需要再输入目标机器的访问密码
允许用户对不同的目标设备有不同的访问权限,例:
对10.0.2.34 有mysql 用户的权限
对192.168.3.22 有root用户的权限
对172.33.24.55 没任何权限
分组管理,即可以对设置进行分组,允许用户访问某组机器,但对组里的不同机器依然有不同的访问权限
二、表结构图
三、
一、作业需求: 1.业务需求 兼顾业务安全目标与用户体验,堡垒机部署后,不应使用户访问业务系统的访问变的复杂,否则工作将很难推进,因为没人喜欢改变现状,尤其是改变后生活变得更艰难 保证堡垒机稳定安全运行, 没有100%的把握,不要上线任何新系统,即使有100%把握,也要做好最坏的打算,想好故障预案 2.功能需求 所有的用户操作日志要保留在数据库中 每个用户登录堡垒机后,只需要选择具体要访问的设置,就连接上了,不需要再输入目标机器的访问密码 允许用户对不同的目标设备有不同的访问权限,例: 对10.0.2.34 有mysql 用户的权限 对192.168.3.22 有root用户的权限 对172.33.24.55 没任何权限 分组管理,即可以对设置进行分组,允许用户访问某组机器,但对组里的不同机器依然有不同的访问权限 二、博客地址:https://www.cnblogs.com/catepython/p/9177109.html 三、运行环境 操作系统:Win10 Python:3.6.4rcl Pycharm:2017.3.4
四、程序架构图
五、核心模块
bin目录
#-*-coding:utf-8 -*- # Author: D.Gray import os,sys BASE_DESC = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #print(BASE_DESC) sys.path.append(BASE_DESC) from modules.actions import excute_from_command_line excute_from_command_line(sys.argv)
conf目录
#-*-coding:utf-8 -*- # Author: D.Gray from modules import views actions = { 'start_session': views.start_session, # 连接server # 'stop': views.stop_server, 'syncdb': views.syncdb, # 同步数据 'create_users': views.create_users, # 创建users 'create_groups': views.create_groups, # 创建组 'create_hosts': views.create_hosts, # 创建主机 'create_bindhosts': views.create_bindhosts, # 创建绑定关系 'create_remoteusers': views.create_remoteusers, # 创建远程用户 'view_user_record': views.user_record_cmd # 查看用户操作命令 }
#-*-coding:utf-8 -*- # Author: D.Gray import sqlalchemy import os,sys BASE_DESC = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #print(BASE_DESC) sys.path.append(BASE_DESC) CONN = 'mysql+pymysql://root:admin1988@localhost/mychine?charset=utf8'
databases目录
#-*-coding:utf-8 -*- # Author: D.Gray import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from sqlalchemy_utils import ChoiceType from sqlalchemy import Column,Integer,String,ForeignKey,UniqueConstraint,Table,Text,DateTime from conf.setting import CONN Base = declarative_base() user_m2m_bind = Table( 'user_m2m_bind',Base.metadata, Column('user_profile_id',Integer,ForeignKey('user_profile.id')), Column('bind_host_id',Integer,ForeignKey('bind_host.id')) ) bind_m2m_group = Table( 'bind_m2m_group',Base.metadata, Column('group_id',Integer,ForeignKey('group.group_id')), Column('bind_host_id',Integer,ForeignKey('bind_host.id')) ) user_m2m_group = Table( 'user_m2m_group',Base.metadata, Column('group_id',Integer,ForeignKey('group.group_id')), Column('user_id',Integer,ForeignKey('user_profile.id')) ) class Host(Base): __tablename__ = 'host' host_id = Column(Integer,primary_key=True) host_name = Column(String(32),unique=True) IP = Column(String(32),nullable=False,unique=True) port = Column(Integer,default=22) def __repr__(self): return '<名称:【%s】 IP:【%s】 port:【%s】>'%(self.host_name,self.IP,self.port) class Group(Base): __tablename__ = 'group' group_id = Column(Integer,primary_key=True) group_name = Column(String(32),nullable=False,unique=True) group_bind = relationship('BindHost',secondary = 'bind_m2m_group',backref = 'groups_key') def __repr__(self): return '<组名:【%s】>'%(self.group_name) class RemUser(Base): ''' 远程登录用户 ''' __tablename__ = 'rem_user' __table_args__ = (UniqueConstraint('auth_type','username','password',name = 'rems_uc'),) id = Column(Integer,primary_key=True) Auth_types = [ ('ssh-password','SSH/Password'), ('ssh-key','SSH/Key'), ] auth_type = Column(ChoiceType(Auth_types)) username = Column(String(32),nullable=False) password = Column(String(32)) def __repr__(self): return '<名称:【%s】 密码:【%s】 验证方式:【%s】>'%(self.username,self.password,self.auth_type) class BindHost(Base): ''' 此表是用来实现操控主机IP 和 登录用户 之间的绑定关系 IP 远程登录名 192.168.111.128 root 192.168.111.129 admin_kyo host_id remuser_id ''' __tablename__ = 'bind_host' __table_args__ = (UniqueConstraint('remuser_id','host_id',name = 'binds_uc'),) id = Column(Integer,primary_key=True) remuser_id = Column(Integer,ForeignKey('rem_user.id'),nullable=False) host_id = Column(Integer,ForeignKey('host.host_id'),nullable=False) bind_hosts = relationship('Host',backref = 'bind_hosts') bind_remusers = relationship('RemUser',backref = 'bind_remusers') def __repr__(self): return '<IP:【%s】 远程登录名:【%s】>' %(self.bind_hosts.IP,self.bind_remusers.username) class UserProfile(Base): ''' 堡垒机用户 ''' __tablename__ = 'user_profile' id = Column(Integer,primary_key=True) user_name = Column(String(32),nullable=False) password = Column(String(32),nullable=False) profile_bind = relationship('BindHost',secondary = 'user_m2m_bind',backref = 'user_profiles') profile_group = relationship('Group',secondary = 'user_m2m_group',backref = 'profile_groups') def __repr__(self): return '<名称:【%s】 密码:【%s】>' %(self.user_name,self.password) class AuditLog(Base): ''' 用户操作日志表 ''' __tablename__ = 'audit_log' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('user_profile.id')) bind_host_id = Column(Integer, ForeignKey('bind_host.id')) action_choices = [ (u'cmd', u'CMD'), (u'login', u'Login'), (u'logout', u'Logout'), ] action_type = Column(ChoiceType(action_choices)) # 命令可能存的数值更大 # cmd = Column(String(255)) cmd = Column(Text(65535)) date = Column(DateTime) user_profile = relationship("UserProfile") bind_host = relationship("BindHost")
modules目录
#-*-coding:utf-8 -*- # Author: D.Gray from conf import action_registers from modules import utils def help_msg(): ''' 帮助函数 print help msgs :return: ''' print("