python-堡垒机制作

巴扎黑
巴扎黑asal
2017-07-18 14:20:292077semak imbas
<br>


堡垒机
windows ,linux 都通过测试
初始化说明:
    #进入根目录
    1、初始化表结构   #python3 bin/start.py syncdb
    2、创建堡垒机用户 #python3 bin/start.py create_users -f share/examples/new_user.yml
    3、创建分组       #python3 bin/start.py create_groups -f share/examples/new_groups.yml
    4、创建远程主机   #python3 bin/start.py create_hosts -f share/examples/new_hosts.yml
    5、创建远程主机用户(绑定堡垒机用户与分组)#python3 bin/start.py create_remoteusers -f share/examples/new_remoteusers.yml
    6、绑定远程主机与远程主机用户【远程绑定组合】(关联远程绑定组合与堡垒机用户、关联远程绑定组合与分组)
        #python3 bin/start.py create_bindhosts -f share/examples/new_bindhosts.yml
    7、登陆堡垒机    #python3 bin/start.py start_session  (示例用户: uge3 密码:uge3)
    8、查看用户日志      #python3 bin/start.py audit -n uge3


plj/#程序目录
|- - -__init__.py
|- - -bin/#启动目录
|      |- - -__init__.py
|      |- - -start.py#启动
|
|- - -conf/#配置目录
|      |- - -__init__.py
|      |- - -action_registers.py#开始参数配置文件
|      |- - -settings.py#配置文件
|
|- - -modules/#主逻辑目录
|      |- - -__init__.py
|      |- - -actions.py#开始函数 帮助信息
|      |- - -db_conn.py#数据库连接配置
|      |- - -interactive.py#ssh命令重写
|      |- - -models.py#表结构 类
|      |- - -ssh_login.py#登陆远程主机调用
|      |- - -utils.py#工具函数
|      |- - -views.py#主要逻辑函数
|
|- - -REDMAE
|
|- - -share/#添加堡垒机用户\远程主机\分组\远程主机用户 目录
|      |- - -examples/#文件目录
|              |- - -new_bindhosts.yml/#远程主机用户与远程主机 组合表(组合表与 分组)(堡垒机用户与组合表) 创建 示例
|              |- - -new_groups.yml/#分组创建 示例( 堡垒机用户与 分组)
|              |- - -new_hosts.yml/#远程主机创建 示例
|              |- - -new_remoteusers.yml/#远程主机用户创建 示例
|              |- - -new_user.yml/#堡垒机用户机创建 示例
plj/#程序目录
|- - -__init__.py
|- - -bin/#启动目录
|      |- - -__init__.py
|      |- - -start.py#启动
 1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #Python  4 #17-7-14    下午6:22 5 #__author__='Administrator' 6  7 import os,sys 8  9 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))10 11 #print(BASE_DIR)12 sys.path.append(BASE_DIR)#加入环境变量13 14 if __name__ == '__main__':15     from modules.actions import excute_from_command_line16     excute_from_command_line(sys.argv)
View Code
|- - -conf/#配置目录
|      |- - -__init__.py
|      |- - -action_registers.py#开始参数配置文件
 1 #_*_coding:utf-8_*_ 2 import os,sys 3  4 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 5  6 sys.path.append(BASE_DIR)#加入环境变量 7  8 from modules import views 9 10 '''11 actions = {12     'start_session': views.start_session,#开始程序13     'stop': views.stop_server,#停止14     'syncdb': views.syncdb,#创建表结构15     'create_users': views.create_users,16     'create_groups': views.create_groups,17     'create_hosts': views.create_hosts,18     'create_bindhosts': views.create_bindhosts,19     'create_remoteusers': views.create_remoteusers,20 }21 '''22 actions = {23     'audit':views.audit,#查看日志24     'start_session': views.start_session,#开始程序25     'stop': views.stop_server,#停止26     'syncdb': views.syncdb,#创建表结构27     'create_users': views.create_users,#创建堡垒机用户28     'create_groups': views.create_groups,#创建分组29     'create_hosts': views.create_hosts,#创建远程主机30     'create_remoteusers': views.create_remoteusers,# #创建远程主机用户31     'create_bindhosts': views.create_bindhosts,# 远程主机与远程主机用户 绑定  关联堡垒机用户与32     #'ass_bind_group': views.ass_bindhost_group,#远程主机与远程主机用户组合 与 分组33 34 35 }36 37 actionses = {38     'audit                  [查看日志]':views.audit,#查看日志39     'start_session          [开始程序]': views.start_session,#开始程序40     'stop                   [停止]': views.stop_server,#停止41     'syncdb                 [创建表结构]': views.syncdb,#创建表结构42     'create_users           [创建堡垒机用户]': views.create_users,#创建堡垒机用户43     'create_groups          [创建分组]': views.create_groups,#创建分组44     'create_hosts           [创建远程主机]': views.create_hosts,#创建远程主机45     'create_remoteusers     [创建远程主机用户]': views.create_remoteusers,# #创建远程主机用户46     'create_bindhosts       [绑定堡垒机用户与远程主机用户]': views.create_bindhosts,#绑定堡垒机用户与远程主机用户47     #'ass_bind_group         [绑定远程主机+远程主机用户组合与分组]': views.ass_bindhost_group,#远程主机与远程主机用户组合 与 分组48 49 50 }
View Code
|      |- - -settings.py#配置文件
 1 import os,sys 2  3 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 4  5 USER='root'#用户名 6 PASSWORD='root'#密码 7 HOST_IP='127.0.0.1'#数据库地址 8 PORT="3306"#数据库端口 9 DB='little_finger'#库名10 DB_CONN ="mysql+pymysql://"+USER+":"+PASSWORD+"@"+HOST_IP+":"+PORT+"/"+DB+"?charset=utf8"#连接参数11 #DB_CONN ="mysql+pymysql://root:root@localhost:3306/"+DB+"?charset=utf8"#连接参数
View Code
|- - -modules/#主逻辑目录
|      |- - -__init__.py
|      |- - -actions.py#开始函数 帮助信息
 1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #Python  4 #17-7-14    下午6:25 5 #__author__='Administrator' 6 import os,sys 7  8 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 9 10 sys.path.append(BASE_DIR)#加入环境变量11 12 from conf import settings13 from conf import action_registers14 from modules import utils15 16 17 def help_msg():#帮助信息18     '''19     print help msgs20     :return:21     '''22     print("\033[31;1mAvailable commands:\033[0m")23     for key in action_registers.actionses:#打印配置文件中的帮助信息24         print("\t",key)25 26 27 def excute_from_command_line(argvs):#接收输入的命令28     if len(argvs) < 2: #如果小于两个词29         help_msg()#打印帮助信息30         exit()31     if argvs[1] not in action_registers.actions:32         utils.print_err("Command [%s] does not exist!" % argvs[1], quit=True)33     action_registers.actions[argvs[1]](argvs[1:])#获取到命令
View Code
|      |- - -db_conn.py#数据库连接配置
 1 from sqlalchemy import create_engine,Table 2 from  sqlalchemy.orm import sessionmaker 3  4 from conf import settings 5  6  7 #engine = create_engine(settings.DB_CONN) 8 engine = create_engine(settings.DB_CONN,echo=True)#数据库连接通道 9 10 SessionCls = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例11 session = SessionCls()
View Code
|      |- - -interactive.py#ssh命令重写
  1 import socket  2 import sys  3 from paramiko.py3compat import u  4 from  modules import models  5 import datetime  6   7 # windows does not have termios...  8 try:  9     import termios 10     import tty 11     has_termios = True 12 except ImportError: 13     has_termios = False 14  15 #记录日志相关              堡垒机用户 连接主机    命令       写入日志 16 def interactive_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording): 17     if has_termios: 18         posix_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording) 19     else: 20         windows_shell(chan) 21  22  23 def posix_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording): 24     import select 25      26     oldtty = termios.tcgetattr(sys.stdin) 27     try: 28         tty.setraw(sys.stdin.fileno()) 29         tty.setcbreak(sys.stdin.fileno()) 30         chan.settimeout(0.0) 31         cmd = &#39;&#39; 32         tab_key = False 33         while True: 34             r, w, e = select.select([chan, sys.stdin], [], [])#select 连接传入命令返回 三个变量 35             if chan in r:#如果命令存在 36                 try: 37                     x = u(chan.recv(1024))#连接返回数据 38                     if tab_key: 39                         if x not in (&#39;\x07&#39; , &#39;\r\n&#39;): #判断空格 和回车 40                             #print(&#39;tab:&#39;,x) 41                             cmd += x 42                         tab_key = False 43                     if len(x) == 0: 44                         sys.stdout.write(&#39;\r\n*** EOF\r\n&#39;) 45                         break 46                     sys.stdout.write(x) 47                     sys.stdout.flush()#实时输出到屏幕 48                 except socket.timeout: 49                     pass 50             if sys.stdin in r: 51                 x = sys.stdin.read(1) 52                 if &#39;\r&#39; != x: 53                     cmd +=x 54                 else: 55  56                     print(&#39;cmd->:',cmd)#命令 57                     log_item = models.AuditLog(user_id=user_obj.id, 58                                           bind_host_id=bind_host_obj.id, 59                                           action_type='cmd', 60                                           cmd=cmd , 61                                           date=datetime.datetime.now() 62                                           ) 63                     cmd_caches.append(log_item)#添加到列表 64                     cmd = '' 65  66                     if len(cmd_caches)>=10:#每十条写入日志 67                         log_recording(user_obj,bind_host_obj,cmd_caches) 68                         cmd_caches = [] 69                 if '\t' == x: 70                     tab_key = True 71                 if len(x) == 0: 72                     break 73                 chan.send(x)#发送命令 74  75     finally: 76         termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) 77  78      79 # thanks to Mike Looijmans for this code 80 def windows_shell(chan): 81     import threading 82  83     sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n") 84          85     def writeall(sock): 86         while True: 87             data = sock.recv(256) 88             if not data: 89                 sys.stdout.write('\r\n*** EOF ***\r\n\r\n') 90                 sys.stdout.flush() 91                 break 92             sys.stdout.write(data.decode())##windows下要转成str 93             sys.stdout.flush()#实时输出到屏幕 94          95     writer = threading.Thread(target=writeall, args=(chan,)) 96     writer.start() 97          98     try: 99         while True:100             d = sys.stdin.read(1)101             if not d:102                 break103             chan.send(d)104     except EOFError:105         # user hit ^Z or F6106         pass
View Code
|      |- - -models.py#表结构 类
  1 #!/usr/bin/env python  2 #_*_coding:utf-8_*_  3 #Python   4 #17-7-12    上午10:54  5 #__author__='Administrator'  6   7 # 创建表  8 import os ,sys  9 BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量 10 sys.path.append(BASE_DIR)#增加环境变量 11 from sqlalchemy.ext.declarative import declarative_base 12 from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index,Table,DATE,DateTime 13 from sqlalchemy.orm import sessionmaker, relationship 14 from sqlalchemy import create_engine 15 from sqlalchemy import func #统计 16 from sqlalchemy_utils import ChoiceType,PasswordType # 17 from  conf import settings 18 Base = declarative_base()#生成orm 基类 19  20 # #创建堡垒机用户关联--联合表,自动维护 21 user_profile_m2m_bind_host = Table('user_profile_m2m_bind_host', Base.metadata, 22                         Column('user_profile_id',Integer,ForeignKey('user_profile.id')),#关联,用户id 23                         Column('bind_host_id',Integer,ForeignKey('bind_host.id')),#关联,联合表id 24                         ) 25 # #创建联合表--分组,自动维护 26 bind_host_m2m_host_group = Table('bind_host_m2m_host_group', Base.metadata, 27                         Column('bind_host_id',Integer,ForeignKey('bind_host.id')),#关联,联合表id 28                         Column('host_group_id',Integer,ForeignKey('host_group.id')),#关联,分组id 29                         ) 30 # #创建堡垒机用户--分组,自动维护 31 user_profile_m2m_host_group = Table('user_profile_m2m_host_group', Base.metadata, 32                         Column('user_profile_id',Integer,ForeignKey('user_profile.id')),#关联,堡垒机用户id 33                         Column('host_group_id',Integer,ForeignKey('host_group.id')),#关联,分组id 34                         ) 35 #主机表 36 class Host(Base):#主机表 37     __tablename__='host' 38     id=Column(Integer,primary_key=True) 39     hostname=Column(String(64),unique=True)#主机名 40     ip=Column(String(64),unique=True)#ip 41     port=Column(Integer,default=22)#端口默认为22 42     def __repr__(self): 43         return self.hostname#输出主机名 44  45 #服务器远程主机用户名密码 46 class RemoteUser(Base): 47     __tablename__='remote_user' 48  49     id=Column(Integer,primary_key=True) 50     AuthType=[ 51         ('ssh-passwd','SSH-Password'), 52         ('ssh-key','SSH-Key'), 53     ] 54     auth_type=Column(ChoiceType(AuthType))#认证类型 55     username=Column(String(64))#用户名 不用唯一 56     password=Column(String(64)) 57     __table_args__=(UniqueConstraint('auth_type','username','password',name='user_password_type'),)#联合只唯一 58     def __repr__(self): 59         return self.username#用户名 60  61 #绑定远程主机-远程用户关联表 62 class BindHost(Base): 63     __tablename__='bind_host' 64     __table_args__=(UniqueConstraint('host_id',"remote_user_id",name='host_id_remote'),)#联合唯一 65     id=Column(Integer,primary_key=True) 66     host_id=Column(Integer,ForeignKey('host.id'))#外键--〉主机表 67     remote_user_id=Column(Integer,ForeignKey('remote_user.id'))#外键--〉主机用户表 68     host=relationship('Host',backref='bind_hosts')#外键  主机表 查询与反查 69     remote_user=relationship('RemoteUser',backref='bind_hosts')#外键 用户表 查询与反查 70     def __repr__(self): 71         return '[主机:%s----->登陆用户:%s]'%(self.host.ip,self.remote_user.username)# 72  73  74 #主机分组 75 class HostGroup(Base): 76     __tablename__='host_group' 77     id=Column(Integer,primary_key=True) 78     group_name=Column(String(64),unique=True)#主机分组名 79     bind_host=relationship('BindHost',secondary=bind_host_m2m_host_group,backref='host_groups')#分组表 远程联合表 查询与反查 80     def __repr__(self): 81         return self.group_name#输出主机名 82  83 #堡垒机用户, 84 class UserProfile(Base): 85     __tablename__='user_profile' 86     id=Column(Integer,primary_key=True) 87     username=Column(String(64),unique=True)#用户名 88     password=Column(String(256)) 89     bind_hosts = relationship('BindHost',secondary=user_profile_m2m_bind_host,backref='user_profiles')#调用关联绑定表查看 堡垒机用户名 90     host_group = relationship('HostGroup',secondary=user_profile_m2m_host_group,backref='user_profiles')#调用关联 分组查看 堡垒机用户名 91     #audit_logs = relationship('AuditLog')#查日志 92     def __repr__(self): 93         return self.username#用户名 94  95 #日志类 96 class AuditLog(Base): 97     __tablename__ = 'audit_log' 98     id = Column(Integer,primary_key=True) 99     user_id = Column(Integer,ForeignKey('user_profile.id'))#外键  堡垒机用户ID100     bind_host_id = Column(Integer,ForeignKey('bind_host.id'))#外键  远程主机ID101     action_choices = [102         (u'cmd',u'CMD'),#命令103         (u'login',u'Login'),#登陆104         (u'logout',u'Logout'),#退出105     ]106     action_type = Column(ChoiceType(action_choices))#日志类型107     cmd = Column(String(255))#命令108     date = Column(DateTime)#日期时间109     user_profile = relationship("UserProfile",backref='audit_logs')#关联堡垒机用户  查询110     bind_host = relationship("BindHost",backref='audit_logs')#关联远程主机   查询
View Code
|      |- - -ssh_login.py#登陆远程主机调用
 1 #!usr/bin/env python 2 #-*-coding:utf-8-*- 3 # Author calmyan  4 #python  5 #2017/7/15    19:44 6 #__author__='Administrator' 7  8  9 import base6410 import getpass11 import os12 import socket13 import sys14 import traceback15 from paramiko.py3compat import input16 from  modules import models17 import datetime18 19 import paramiko20 try:21     import interactive22 except ImportError:23     from . import interactive24 25 #登陆远程主机26 def ssh_login(user_obj,bind_host_obj,mysql_engine,log_recording):#ssh进入远程主机27     # now, connect and use paramiko Client to negotiate SSH2 across the connection28     try:29         client = paramiko.SSHClient()30         client.load_system_host_keys()31         client.set_missing_host_key_policy(paramiko.WarningPolicy())32         print('*** Connecting...')#开始连接33         #client.connect(hostname, port, username, password)34         client.connect(bind_host_obj.host.ip,35                        bind_host_obj.host.port,36                        bind_host_obj.remote_user.username,37                        bind_host_obj.remote_user.password,38                        timeout=30)#超时30秒39 40         cmd_caches = []#定义一个列表,暂时保存命令41         chan = client.invoke_shell()42         print(repr(client.get_transport()))43         print('*** Here we go!\n')44         cmd_caches.append(models.AuditLog(user_id=user_obj.id,45                                           bind_host_id=bind_host_obj.id,46                                           action_type='login',47                                           date=datetime.datetime.now()48                                           ))49         log_recording(user_obj,bind_host_obj,cmd_caches)50         interactive.interactive_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)#传入 堡垒机用户, 连接远程主机 命令 记当日志函数51         chan.close()52         client.close()53 54     except Exception as e:55         print('*** Caught exception: %s: %s' % (e.__class__, e))56         traceback.print_exc()57         try:58             client.close()59         except:60             pass61         sys.exit(1)
View Code
|      |- - -utils.py#工具函数
 1 from conf import settings 2 import yaml 3 try: 4     from yaml import CLoader as Loader, CDumper as Dumper 5 except ImportError: 6     from yaml import Loader, Dumper 7  8 def print_err(msg,quit=False):#错误提示输出 9     output = "\033[31;1mError: %s\033[0m" % msg10     if quit:11         exit(output)12     else:13         print(output)14 15 16 def yaml_parser(yml_filename):17     '''18     load yaml file and return19     :param yml_filename:20     :return:21     '''22     #yml_filename = "%s/%s.yml" % (settings.StateFileBaseDir,yml_filename)23     try:24         yaml_file = open(yml_filename,'r')#打开文件25         data = yaml.load(yaml_file)#load 成一个对象26         return data#返回数据27     except Exception as e:28         print_err(e)
View Code
|      |- - -views.py#主要逻辑函数
  1 #_*_coding:utf-8_*_  2 import os,sys  3 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  4   5 sys.path.append(BASE_DIR)#加入环境变量  6 from modules import models  7 from modules.db_conn import engine,session  8 from modules.utils import print_err,yaml_parser  9 #from modules import common_filt 10 from modules import ssh_login 11 from sqlalchemy import create_engine,Table 12 from  sqlalchemy.orm import sessionmaker 13  14 from conf import settings 15  16 #用户登陆函数 17 def auth(): 18     ''' 19     do the user login authentication 20     :return: 21     ''' 22     count = 0 23     while count <3:#用户输入三次机会 24         username = input("\033[32;1mUsername:\033[0m").strip() 25         if len(username) ==0:continue 26         password = input("\033[32;1mPassword:\033[0m").strip() 27         if len(password) ==0:continue 28         user_obj = session.query(models.UserProfile).filter(models.UserProfile.username==username, 29                                                             models.UserProfile.password==password).first()#从数据库中获取堡垒机用户信息 30         if user_obj: 31             return user_obj 32         else: 33             print("wrong username or password, you have %s more chances." %(3-count-1)) 34             count +=1 35     else: 36         print_err("too many attempts.") 37  38  39 #欢迎界面 40 def welcome_msg(user): 41     WELCOME_MSG = &#39;&#39;&#39;\033[32;1m 42     ------------- Welcome [%s] login LittleFinger ------------- 43     \033[0m&#39;&#39;&#39;%  user.username 44     print(WELCOME_MSG) 45  46  47 #写入数据库 日志 48 def log_recording(user_obj,bind_host_obj,logs): 49     &#39;&#39;&#39; 50     flush user operations on remote host into DB 51     :param user_obj: 52     :param bind_host_obj: 53     :param logs: list format [logItem1,logItem2,...] 54     :return: 55     &#39;&#39;&#39; 56     print("\033[41;1m--logs:\033[0m",logs) 57     session.add_all(logs) 58     session.commit() 59  60 #开始函数 61 def start_session(argvs): 62     print(&#39;going to start sesssion &#39;) 63     user = auth()#判断用户名 并返回用户对应信息 64     if user: 65         welcome_msg(user)#打印欢迎界面 66         #print(user.id)#用户ID 67         #print(user.bind_hosts)#绑定主机 68         #print(user.host_group)#所在组 69         #log_recording(user,user.bind_hosts,user.host_group,logs) 70         exit_flag = False#设定点 为假 71         while not exit_flag:#如果设定点 为假 说明登陆成功 72             if user.bind_hosts:#有绑定远程主机 打印远程主机 73                 print(&#39;\033[32;1mz.\tungroupped hosts (%s)\033[0m&#39; %len(user.bind_hosts) ) 74             for index,group in enumerate(user.host_group):#打印当前用户所在组 75                 print(&#39;\033[32;1m%s.\t%s (%s)\033[0m&#39; %(index,group.group_name,  len(group.bind_host)) ) 76  77             print(&#39;(q)=quit&#39;) 78             choice = input("[%s]:" % user.username).strip()#开始获取输入的命令 79  80             if len(choice) == 0:continue#如果没有输入跳过 81             if choice == &#39;q&#39;: 82                 exit_flag=True 83             #if choice==&#39;exit&#39;: exit()#退出 84             if choice == &#39;z&#39;:#如果输入 z 85                 print("------ Group: ungroupped hosts ------" )#输出所有的未分组的主机 86                 for index,bind_host in enumerate(user.bind_hosts): 87                     print("  %s.\t%s@%s(%s)"%(index, 88                                               bind_host.remote_user.username,#绑定的用户名 89                                               bind_host.host.hostname,#主机名 90                                               bind_host.host.ip,#IP地址 91                                               )) 92                 print("----------- END -----------" ) 93             elif choice.isdigit():#如果是选择数字 94                 choice = int(choice) 95                 if choice < len(user.host_group): 96                     print("------ Group: %s ------"  % user.host_group[choice].group_name ) 97                     for index,bind_host in enumerate(user.host_group[choice].bind_host):#打印出选择组的包括的 98                         print("  %s.\t%s@%s(%s)"%(index, 99                                                   bind_host.remote_user.username,#绑定的用户名100                                                   bind_host.host.hostname,#主机名101                                                   bind_host.host.ip,#IP地址102                                                   ))103                     print("----------- END -----------" )104 105                     #host selection106                     while not exit_flag:107                         user_option = input("[(b)back, (q)quit, select host to login]:").strip()108                         if len(user_option)==0:continue109                         if user_option == &#39;b&#39;:break110                         if user_option == &#39;q&#39;:111                             exit_flag=True112                         if user_option.isdigit():113                             user_option = int(user_option)114                             if user_option < len(user.host_group[choice].bind_host) :#查看分组所绑定的远程 主机115                                 print(&#39;host:&#39;,user.host_group[choice].bind_host[user_option])116                                 print(&#39;audit log:&#39;,user.host_group[choice].bind_host[user_option].audit_logs)117                                 ssh_login.ssh_login(user,118                                                     user.host_group[choice].bind_host[user_option],119                                                     session,120                                                     log_recording)121                 else:122                     print("no this option..")123 124 #停止退出125 def stop_server(argvs):126     exit()127 128 #创建表结构129 def syncdb(argvs):130     print("Syncing DB....[创建所有表结构]")131     models.Base.metadata.create_all(engine) #创建所有表结构132 133 &#39;&#39;&#39;======创建四个基础表====  &#39;&#39;&#39;134 #堡垒机用户添加135 def create_users(argvs):136     if &#39;-f&#39; in argvs:#判断参数 -f 是否存在137         user_file  = argvs[argvs.index("-f") +1 ]#获取文件位置138     else:139         print_err("invalid usage, should be:\ncreateusers -f <the new users file>",quit=True)140     source = yaml_parser(user_file)#获取文件内容数据141     if source:#如果获取成功142         for key,val in source.items():143             print(key,val)144             obj = models.UserProfile(username=key,password=val.get('password'))#创建新数据145             session.add(obj)146         session.commit()147 148 #分组添加149 def create_groups(argvs):150     if '-f' in argvs:#判断参数 -f 是否存在151         group_file  = argvs[argvs.index("-f") +1 ]152     else:153         print_err("invalid usage, should be:\ncreategroups -f <the new groups file>",quit=True)154     source = yaml_parser(group_file)#通过yaml 获取文件中的数据,155     if source:156         for key,val in source.items():157             print(key,val)158             obj = models.HostGroup(group_name=key)#创建一条新数据159             if val.get('bind_hosts'):#160                 bind_hosts = bind_hosts_filter(val)#绑定的远程主机组合表161                 obj.bind_host = bind_hosts162             if val.get('user_profiles'):#堡垒机用户163                 user_profiles = user_profiles_filter(val)#堡垒机用户164                 obj.user_profiles = user_profiles165             session.add(obj)166         session.commit()167 168 #远程主机添加169 def create_hosts(argvs):170     if '-f' in argvs:#判断参数 -f 是否存在171         hosts_file  = argvs[argvs.index("-f") +1 ]172     else:173         print_err("invalid usage, should be:\ncreate_hosts -f <the new hosts file>",quit=True)#退出函数174     source = yaml_parser(hosts_file)#通过yaml 获取文件中的数据,175     if source:#如果获取成功,不为空176         for key,val in source.items():#进行数据的解析177             print(key)178             print(val)179             obj = models.Host(hostname=key,ip=val.get('ip'), port=val.get('port') or 22)#port 端口默认为22180             session.add(obj)#写入到数据库181         session.commit()#关闭 确认写入182 183 #创建远程主机用户184 def create_remoteusers(argvs):185     if '-f' in argvs:186         remoteusers_file  = argvs[argvs.index("-f") +1 ]187     else:188         print_err("invalid usage, should be:\ncreate_remoteusers -f <the new remoteusers file>",quit=True)189     source = yaml_parser(remoteusers_file)#通过yaml 获取文件中的数据,190     if source:191         for key,val in source.items():#进行数据的解析192             print(key,val)193             obj = models.RemoteUser(username=val.get('username'),auth_type=val.get('auth_type'),password=val.get('password'))194             session.add(obj)#写入数据库195         session.commit()196 197 198 '''====远程主机与远程主机用户组合表====='''199 ##远程主机用户名密码与远程主机组合绑定   关联 到堡垒机用户200 def create_bindhosts(argvs):201     if '-f' in argvs:202         bindhosts_file  = argvs[argvs.index("-f") +1 ]203     else:204         print_err("invalid usage, should be:\ncreate_hosts -f <the new bindhosts file>",quit=True)205     source = yaml_parser(bindhosts_file)#通过yaml 获取文件中的数据,206     if source:207         for key,val in source.items():208             print(key,val)209             host_obj = session.query(models.Host).filter(models.Host.hostname==val.get('hostname')).first()#获取对应主机数据210             assert host_obj#断言 当前主机一定要存在才能往下执行211             for item in val['remote_users']:#输出存在的远程主机用户212                 print(item )213                 assert item.get('auth_type')#断言 一定要存在才能往下执行214                 if item.get('auth_type') == 'ssh-passwd':#判断ssh连接类型 从数据库选出合条件的数据215                     remoteuser_obj = session.query(models.RemoteUser).filter(216                                                         models.RemoteUser.username==item.get('username'),217                                                         models.RemoteUser.password==item.get('password')218                                                     ).first()#获取主机数据 返回对象219                 else:220                     remoteuser_obj = session.query(models.RemoteUser).filter(221                                                         models.RemoteUser.username==item.get('username'),222                                                         models.RemoteUser.auth_type==item.get('auth_type'),223                                                     ).first()224                 if not remoteuser_obj:#如果远程主机用户不存在225                     print_err("RemoteUser obj %s does not exist." % item,quit=True )226                 bindhost_obj = models.BindHost(host_id=host_obj.id,remote_user_id=remoteuser_obj.id)#创建一条新数据227                 session.add(bindhost_obj)228                 #for groups this host binds to229                 if source[key].get('groups'):#如果有分组标志230                     #获取分组信息231                     group_objs = session.query(models.HostGroup).filter(models.HostGroup.group_name.in_(source[key].get('groups') )).all()232                     assert group_objs#断言  分组一定要存在才能往下执行233                     print('groups:', group_objs)234                     bindhost_obj.host_groups = group_objs#主机加到分组235                 #for user_profiles this host binds to236                 if source[key].get('user_profiles'):#如果有堡垒机用户标志237                     #获取堡垒机用信息238                     userprofile_objs = session.query(models.UserProfile).filter(models.UserProfile.username.in_(239                         source[key].get('user_profiles')240                     )).all()241                     assert userprofile_objs#断言 堡垒机用户一定要存在才能往下执行242                     print("userprofiles:",userprofile_objs)243                     bindhost_obj.user_profiles = userprofile_objs#主机与堡垒机用户绑定244                 #print(bindhost_obj)245         session.commit()246 247 248 #远程主机组合表查看249 def bind_hosts_filter(vals):#远程主机组合表查看250     print('**>',vals.get('bind_hosts') )251     bind_hosts = session.query(models.BindHost).filter(models.Host.hostname.in_(vals.get('bind_hosts'))).all()252     if not bind_hosts:253         print_err("none of [%s] exist in bind_host table." % vals.get('bind_hosts'),quit=True)254     return bind_hosts255 256 #堡垒机用户查看257 def user_profiles_filter(vals):258     user_profiles = session.query(models.UserProfile).filter(models.UserProfile.username.in_(vals.get('user_profiles'))).all()259     if not user_profiles:260         print_err("none of [%s] exist in user_profile table." % vals.get('user_profiles'),quit=True)261     return  user_profiles262 263 264 265 #查看用户日志266 def audit(argvs):267     if '-n' in argvs:268         user_name  = argvs[argvs.index("-n") +1 ]#获取要查看的用户名269     else:270         print_err("invalid usage, should be:\n输入参数 -n <用户名/user_name >",quit=True)271     print(user_name)272     user_obj = session.query(models.UserProfile).filter(models.UserProfile.username==user_name).first()#取到273     print(user_obj.id)274     log_obj = session.query(models.AuditLog).filter(models.AuditLog.user_id==user_obj.id).all()275     for i in log_obj:276         print('堡垒机用户:【%s】,远程主机【%s】,远程用户:【%s】命令:【%s】,日期:【%s】'%(i.user_profile,i.bind_host.host,i.bind_host.remote_user,i.cmd,i.date))277     input('========')
View Code

 

|- - -share/#添加堡垒机用户\远程主机\分组\远程主机用户 目录
|      |- - -examples/#文件目录
|              |- - -new_bindhosts.yml/#远程主机用户与远程主机 组合表(组合表与 分组)(堡垒机用户与组合表) 创建 示例
 1 bind0: 2   hostname: ubuntu test 3   remote_users: 4     - user0: 5       username: root 6       auth_type: ssh-passwd 7       password: root 8   groups: 9     - test_group10   user_profiles:11     - uge312     - alex13 14 15 bind1:16   hostname: server117   remote_users:18     - user1:19       username: root20       auth_type: ssh-key21       #password: 12322     - user0:23       username: root24       auth_type: ssh-passwd25       password: root26     - user4:27       username: calmyan28       auth_type: ssh-passwd29       password: yjj30   groups:31     - bj_group32   user_profiles:33     - uge334 35 bind2:36   hostname: server237   remote_users:38     - user1:39       username: alex40       auth_type: ssh-passwd41       password: alex371442   groups:43     - bj_group44     - sh_group45   user_profiles:46     - rain
View Code
|              |- - -new_groups.yml/#分组创建 示例( 堡垒机用户与 分组)
 1 bj_group: 2   user_profiles: 3     - alex 4     - uge3 5  6 sh_group: 7   user_profiles: 8     - jack 9     - alex10     - rain11     - uge312 test_group:13   user_profiles:14     - uge3
View Code
|              |- - -new_hosts.yml/#远程主机创建 示例
 1 ubuntu test: 2   ip: 192.168.11.50 3   port: 22 4  5 server1: 6   ip: 192.168.11.51 7  8  9 server2:10   ip: 10.4.4.2211   port: 30000
View Code
|              |- - -new_remoteusers.yml/#远程主机用户创建 示例
 1 user0: 2   auth_type:  ssh-passwd 3   username: root 4   password: root 5  6 user1: 7   auth_type:  ssh-passwd 8   username: root 9   password: alex!3432110 11 user2:12   auth_type:  ssh-key13   username: root14   #password: abc!2315 16 user3:17   auth_type:  ssh-passwd18   username: alex19   password: alex371420 21 user4:22   auth_type:  ssh-passwd23   username: calmyan24   password: yjj
View Code
|              |- - -new_user.yml/#堡垒机用户机创建 示例
 1 alex: 2   password: alex123 3 uge3: 4   password: uge3 5  6 jack: 7   password: jack123 8  9 rain:10   password: rain123
View Code

 

<br><br>

Atas ialah kandungan terperinci python-堡垒机制作. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn