• python第七十六天--堡垒机完成


    
    



    堡垒机
    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_line
    16     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 settings
    13 from conf import action_registers
    14 from modules import utils
    15 
    16 
    17 def help_msg():#帮助信息
    18     '''
    19     print help msgs
    20     :return:
    21     '''
    22     print("33[31;1mAvailable commands:33[0m")
    23     for key in action_registers.actionses:#打印配置文件中的帮助信息
    24         print("	",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 = ''
     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 ('x07' , '
    '): #判断空格 和回车
     40                             #print('tab:',x)
     41                             cmd += x
     42                         tab_key = False
     43                     if len(x) == 0:
     44                         sys.stdout.write('
    *** EOF
    ')
     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 '
    ' != x:
     53                     cmd +=x
     54                 else:
     55 
     56                     print('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 '	' == 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.
    
    ")
     84         
     85     def writeall(sock):
     86         while True:
     87             data = sock.recv(256)
     88             if not data:
     89                 sys.stdout.write('
    *** EOF ***
    
    ')
     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                 break
    103             chan.send(d)
    104     except EOFError:
    105         # user hit ^Z or F6
    106         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'))#外键  堡垒机用户ID
    100     bind_host_id = Column(Integer,ForeignKey('bind_host.id'))#外键  远程主机ID
    101     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 base64
    10 import getpass
    11 import os
    12 import socket
    13 import sys
    14 import traceback
    15 from paramiko.py3compat import input
    16 from  modules import models
    17 import datetime
    18 
    19 import paramiko
    20 try:
    21     import interactive
    22 except ImportError:
    23     from . import interactive
    24 
    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 connection
    28     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!
    ')
    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             pass
    61         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 = "33[31;1mError: %s33[0m" % msg
    10     if quit:
    11         exit(output)
    12     else:
    13         print(output)
    14 
    15 
    16 def yaml_parser(yml_filename):
    17     '''
    18     load yaml file and return
    19     :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("33[32;1mUsername:33[0m").strip()
     25         if len(username) ==0:continue
     26         password = input("33[32;1mPassword:33[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 = '''33[32;1m
     42     ------------- Welcome [%s] login LittleFinger -------------
     43     33[0m'''%  user.username
     44     print(WELCOME_MSG)
     45 
     46 
     47 #写入数据库 日志
     48 def log_recording(user_obj,bind_host_obj,logs):
     49     '''
     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     '''
     56     print("33[41;1m--logs:33[0m",logs)
     57     session.add_all(logs)
     58     session.commit()
     59 
     60 #开始函数
     61 def start_session(argvs):
     62     print('going to start sesssion ')
     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('33[32;1mz.	ungroupped hosts (%s)33[0m' %len(user.bind_hosts) )
     74             for index,group in enumerate(user.host_group):#打印当前用户所在组
     75                 print('33[32;1m%s.	%s (%s)33[0m' %(index,group.group_name,  len(group.bind_host)) )
     76 
     77             print('(q)=quit')
     78             choice = input("[%s]:" % user.username).strip()#开始获取输入的命令
     79 
     80             if len(choice) == 0:continue#如果没有输入跳过
     81             if choice == 'q':
     82                 exit_flag=True
     83             #if choice=='exit': exit()#退出
     84             if choice == 'z':#如果输入 z
     85                 print("------ Group: ungroupped hosts ------" )#输出所有的未分组的主机
     86                 for index,bind_host in enumerate(user.bind_hosts):
     87                     print("  %s.	%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.	%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 selection
    106                     while not exit_flag:
    107                         user_option = input("[(b)back, (q)quit, select host to login]:").strip()
    108                         if len(user_option)==0:continue
    109                         if user_option == 'b':break
    110                         if user_option == 'q':
    111                             exit_flag=True
    112                         if user_option.isdigit():
    113                             user_option = int(user_option)
    114                             if user_option < len(user.host_group[choice].bind_host) :#查看分组所绑定的远程 主机
    115                                 print('host:',user.host_group[choice].bind_host[user_option])
    116                                 print('audit log:',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 '''======创建四个基础表====  '''
    134 #堡垒机用户添加
    135 def create_users(argvs):
    136     if '-f' in argvs:#判断参数 -f 是否存在
    137         user_file  = argvs[argvs.index("-f") +1 ]#获取文件位置
    138     else:
    139         print_err("invalid usage, should be:
    createusers -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:
    creategroups -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_hosts
    162             if val.get('user_profiles'):#堡垒机用户
    163                 user_profiles = user_profiles_filter(val)#堡垒机用户
    164                 obj.user_profiles = user_profiles
    165             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:
    create_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 端口默认为22
    180             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:
    create_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:
    create_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 to
    229                 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 to
    236                 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_hosts
    255 
    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_profiles
    262 
    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 <用户名/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_group
    10   user_profiles:
    11     - uge3
    12     - alex
    13 
    14 
    15 bind1:
    16   hostname: server1
    17   remote_users:
    18     - user1:
    19       username: root
    20       auth_type: ssh-key
    21       #password: 123
    22     - user0:
    23       username: root
    24       auth_type: ssh-passwd
    25       password: root
    26     - user4:
    27       username: calmyan
    28       auth_type: ssh-passwd
    29       password: yjj
    30   groups:
    31     - bj_group
    32   user_profiles:
    33     - uge3
    34 
    35 bind2:
    36   hostname: server2
    37   remote_users:
    38     - user1:
    39       username: alex
    40       auth_type: ssh-passwd
    41       password: alex3714
    42   groups:
    43     - bj_group
    44     - sh_group
    45   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     - alex
    10     - rain
    11     - uge3
    12 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.22
    11   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!34321
    10 
    11 user2:
    12   auth_type:  ssh-key
    13   username: root
    14   #password: abc!23
    15 
    16 user3:
    17   auth_type:  ssh-passwd
    18   username: alex
    19   password: alex3714
    20 
    21 user4:
    22   auth_type:  ssh-passwd
    23   username: calmyan
    24   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


  • 相关阅读:
    黄聪:C#中CefSharp的简单使用
    ArcGIS Pro关闭窗口和退出
    AddOverlay
    ArcGIS Pro固定纸张限定比例尺自动调整纵横打印
    ArcGIS pro增加一个独立表到地图
    ArcGIS Pro How to remove standalone table from contents
    ArcGIS Pro的进度条
    CreatePolygonGraphicElement
    Creating a Group with a List of Elements
    ArcGISPro理解多线程
  • 原文地址:https://www.cnblogs.com/uge3/p/7196514.html
Copyright © 2020-2023  润新知