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

时间:2023-03-10 01:57:40
python第七十六天--堡垒机完成

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#启动
 #!/usr/bin/env python
#_*_coding:utf-8_*_
#Python
#17-7-14 下午6:22
#__author__='Administrator' import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #print(BASE_DIR)
sys.path.append(BASE_DIR)#加入环境变量 if __name__ == '__main__':
from modules.actions import excute_from_command_line
excute_from_command_line(sys.argv)
|- - -conf/#配置目录
| |- - -__init__.py
| |- - -action_registers.py#开始参数配置文件
 #_*_coding:utf-8_*_
import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR)#加入环境变量 from modules import views '''
actions = {
'start_session': views.start_session,#开始程序
'stop': views.stop_server,#停止
'syncdb': views.syncdb,#创建表结构
'create_users': views.create_users,
'create_groups': views.create_groups,
'create_hosts': views.create_hosts,
'create_bindhosts': views.create_bindhosts,
'create_remoteusers': views.create_remoteusers,
}
'''
actions = {
'audit':views.audit,#查看日志
'start_session': views.start_session,#开始程序
'stop': views.stop_server,#停止
'syncdb': views.syncdb,#创建表结构
'create_users': views.create_users,#创建堡垒机用户
'create_groups': views.create_groups,#创建分组
'create_hosts': views.create_hosts,#创建远程主机
'create_remoteusers': views.create_remoteusers,# #创建远程主机用户
'create_bindhosts': views.create_bindhosts,# 远程主机与远程主机用户 绑定 关联堡垒机用户与
#'ass_bind_group': views.ass_bindhost_group,#远程主机与远程主机用户组合 与 分组 } actionses = {
'audit [查看日志]':views.audit,#查看日志
'start_session [开始程序]': views.start_session,#开始程序
'stop [停止]': views.stop_server,#停止
'syncdb [创建表结构]': views.syncdb,#创建表结构
'create_users [创建堡垒机用户]': views.create_users,#创建堡垒机用户
'create_groups [创建分组]': views.create_groups,#创建分组
'create_hosts [创建远程主机]': views.create_hosts,#创建远程主机
'create_remoteusers [创建远程主机用户]': views.create_remoteusers,# #创建远程主机用户
'create_bindhosts [绑定堡垒机用户与远程主机用户]': views.create_bindhosts,#绑定堡垒机用户与远程主机用户
#'ass_bind_group [绑定远程主机+远程主机用户组合与分组]': views.ass_bindhost_group,#远程主机与远程主机用户组合 与 分组 }
|      |- - -settings.py#配置文件
 import os,sys

 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

 USER='root'#用户名
PASSWORD='root'#密码
HOST_IP='127.0.0.1'#数据库地址
PORT=""#数据库端口
DB='little_finger'#库名
DB_CONN ="mysql+pymysql://"+USER+":"+PASSWORD+"@"+HOST_IP+":"+PORT+"/"+DB+"?charset=utf8"#连接参数
#DB_CONN ="mysql+pymysql://root:root@localhost:3306/"+DB+"?charset=utf8"#连接参数
|- - -modules/#主逻辑目录
| |- - -__init__.py
| |- - -actions.py#开始函数 帮助信息
 #!/usr/bin/env python
#_*_coding:utf-8_*_
#Python
#17-7-14 下午6:25
#__author__='Administrator'
import os,sys BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR)#加入环境变量 from conf import settings
from conf import action_registers
from modules import utils def help_msg():#帮助信息
'''
print help msgs
:return:
'''
print("\033[31;1mAvailable commands:\033[0m")
for key in action_registers.actionses:#打印配置文件中的帮助信息
print("\t",key) def excute_from_command_line(argvs):#接收输入的命令
if len(argvs) < 2: #如果小于两个词
help_msg()#打印帮助信息
exit()
if argvs[1] not in action_registers.actions:
utils.print_err("Command [%s] does not exist!" % argvs[1], quit=True)
action_registers.actions[argvs[1]](argvs[1:])#获取到命令
|      |- - -db_conn.py#数据库连接配置
 from sqlalchemy import create_engine,Table
from sqlalchemy.orm import sessionmaker from conf import settings #engine = create_engine(settings.DB_CONN)
engine = create_engine(settings.DB_CONN,echo=True)#数据库连接通道 SessionCls = sessionmaker(bind=engine) #创建与数据库的会话session class ,注意,这里返回给session的是个class,不是实例
session = SessionCls()
|      |- - -interactive.py#ssh命令重写
 import socket
import sys
from paramiko.py3compat import u
from modules import models
import datetime # windows does not have termios...
try:
import termios
import tty
has_termios = True
except ImportError:
has_termios = False #记录日志相关 堡垒机用户 连接主机 命令 写入日志
def interactive_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording):
if has_termios:
posix_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)
else:
windows_shell(chan) def posix_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording):
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], [], [])#select 连接传入命令返回 三个变量
if chan in r:#如果命令存在
try:
x = u(chan.recv(1024))#连接返回数据
if tab_key:
if x not in ('\x07' , '\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
else: print('cmd->:',cmd)#命令
log_item = models.AuditLog(user_id=user_obj.id,
bind_host_id=bind_host_obj.id,
action_type='cmd',
cmd=cmd ,
date=datetime.datetime.now()
)
cmd_caches.append(log_item)#添加到列表
cmd = '' if len(cmd_caches)>=10:#每十条写入日志
log_recording(user_obj,bind_host_obj,cmd_caches)
cmd_caches = []
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.decode())##windows下要转成str
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
|      |- - -models.py#表结构 类
 #!/usr/bin/env python
#_*_coding:utf-8_*_
#Python
#17-7-12 上午10:54
#__author__='Administrator' # 创建表
import os ,sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))#获取相对路径转为绝对路径赋于变量
sys.path.append(BASE_DIR)#增加环境变量
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index,Table,DATE,DateTime
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine
from sqlalchemy import func #统计
from sqlalchemy_utils import ChoiceType,PasswordType #
from conf import settings
Base = declarative_base()#生成orm 基类 # #创建堡垒机用户关联--联合表,自动维护
user_profile_m2m_bind_host = Table('user_profile_m2m_bind_host', Base.metadata,
Column('user_profile_id',Integer,ForeignKey('user_profile.id')),#关联,用户id
Column('bind_host_id',Integer,ForeignKey('bind_host.id')),#关联,联合表id
)
# #创建联合表--分组,自动维护
bind_host_m2m_host_group = Table('bind_host_m2m_host_group', Base.metadata,
Column('bind_host_id',Integer,ForeignKey('bind_host.id')),#关联,联合表id
Column('host_group_id',Integer,ForeignKey('host_group.id')),#关联,分组id
)
# #创建堡垒机用户--分组,自动维护
user_profile_m2m_host_group = Table('user_profile_m2m_host_group', Base.metadata,
Column('user_profile_id',Integer,ForeignKey('user_profile.id')),#关联,堡垒机用户id
Column('host_group_id',Integer,ForeignKey('host_group.id')),#关联,分组id
)
#主机表
class Host(Base):#主机表
__tablename__='host'
id=Column(Integer,primary_key=True)
hostname=Column(String(64),unique=True)#主机名
ip=Column(String(64),unique=True)#ip
port=Column(Integer,default=22)#端口默认为22
def __repr__(self):
return self.hostname#输出主机名 #服务器远程主机用户名密码
class RemoteUser(Base):
__tablename__='remote_user' id=Column(Integer,primary_key=True)
AuthType=[
('ssh-passwd','SSH-Password'),
('ssh-key','SSH-Key'),
]
auth_type=Column(ChoiceType(AuthType))#认证类型
username=Column(String(64))#用户名 不用唯一
password=Column(String(64))
__table_args__=(UniqueConstraint('auth_type','username','password',name='user_password_type'),)#联合只唯一
def __repr__(self):
return self.username#用户名 #绑定远程主机-远程用户关联表
class BindHost(Base):
__tablename__='bind_host'
__table_args__=(UniqueConstraint('host_id',"remote_user_id",name='host_id_remote'),)#联合唯一
id=Column(Integer,primary_key=True)
host_id=Column(Integer,ForeignKey('host.id'))#外键--〉主机表
remote_user_id=Column(Integer,ForeignKey('remote_user.id'))#外键--〉主机用户表
host=relationship('Host',backref='bind_hosts')#外键 主机表 查询与反查
remote_user=relationship('RemoteUser',backref='bind_hosts')#外键 用户表 查询与反查
def __repr__(self):
return '[主机:%s----->登陆用户:%s]'%(self.host.ip,self.remote_user.username)# #主机分组
class HostGroup(Base):
__tablename__='host_group'
id=Column(Integer,primary_key=True)
group_name=Column(String(64),unique=True)#主机分组名
bind_host=relationship('BindHost',secondary=bind_host_m2m_host_group,backref='host_groups')#分组表 远程联合表 查询与反查
def __repr__(self):
return self.group_name#输出主机名 #堡垒机用户,
class UserProfile(Base):
__tablename__='user_profile'
id=Column(Integer,primary_key=True)
username=Column(String(64),unique=True)#用户名
password=Column(String(256))
bind_hosts = relationship('BindHost',secondary=user_profile_m2m_bind_host,backref='user_profiles')#调用关联绑定表查看 堡垒机用户名
host_group = relationship('HostGroup',secondary=user_profile_m2m_host_group,backref='user_profiles')#调用关联 分组查看 堡垒机用户名
#audit_logs = relationship('AuditLog')#查日志
def __repr__(self):
return self.username#用户名 #日志类
class AuditLog(Base):
__tablename__ = 'audit_log'
id = Column(Integer,primary_key=True)
user_id = Column(Integer,ForeignKey('user_profile.id'))#外键 堡垒机用户ID
bind_host_id = Column(Integer,ForeignKey('bind_host.id'))#外键 远程主机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))#命令
date = Column(DateTime)#日期时间
user_profile = relationship("UserProfile",backref='audit_logs')#关联堡垒机用户 查询
bind_host = relationship("BindHost",backref='audit_logs')#关联远程主机 查询
|      |- - -ssh_login.py#登陆远程主机调用
 #!usr/bin/env python
#-*-coding:utf-8-*-
# Author calmyan
#python
#2017/7/15 19:44
#__author__='Administrator' import base64
import getpass
import os
import socket
import sys
import traceback
from paramiko.py3compat import input
from modules import models
import datetime import paramiko
try:
import interactive
except ImportError:
from . import interactive #登陆远程主机
def ssh_login(user_obj,bind_host_obj,mysql_engine,log_recording):#ssh进入远程主机
# now, connect and use paramiko Client to negotiate SSH2 across the connection
try:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
print('*** Connecting...')#开始连接
#client.connect(hostname, port, username, password)
client.connect(bind_host_obj.host.ip,
bind_host_obj.host.port,
bind_host_obj.remote_user.username,
bind_host_obj.remote_user.password,
timeout=30)#超时30秒 cmd_caches = []#定义一个列表,暂时保存命令
chan = client.invoke_shell()
print(repr(client.get_transport()))
print('*** Here we go!\n')
cmd_caches.append(models.AuditLog(user_id=user_obj.id,
bind_host_id=bind_host_obj.id,
action_type='login',
date=datetime.datetime.now()
))
log_recording(user_obj,bind_host_obj,cmd_caches)
interactive.interactive_shell(chan,user_obj,bind_host_obj,cmd_caches,log_recording)#传入 堡垒机用户, 连接远程主机 命令 记当日志函数
chan.close()
client.close() except Exception as e:
print('*** Caught exception: %s: %s' % (e.__class__, e))
traceback.print_exc()
try:
client.close()
except:
pass
sys.exit(1)
|      |- - -utils.py#工具函数
 from conf import settings
import yaml
try:
from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
from yaml import Loader, Dumper def print_err(msg,quit=False):#错误提示输出
output = "\033[31;1mError: %s\033[0m" % msg
if quit:
exit(output)
else:
print(output) def yaml_parser(yml_filename):
'''
load yaml file and return
:param yml_filename:
:return:
'''
#yml_filename = "%s/%s.yml" % (settings.StateFileBaseDir,yml_filename)
try:
yaml_file = open(yml_filename,'r')#打开文件
data = yaml.load(yaml_file)#load 成一个对象
return data#返回数据
except Exception as e:
print_err(e)
|      |- - -views.py#主要逻辑函数
 #_*_coding:utf-8_*_
import os,sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR)#加入环境变量
from modules import models
from modules.db_conn import engine,session
from modules.utils import print_err,yaml_parser
#from modules import common_filt
from modules import ssh_login
from sqlalchemy import create_engine,Table
from sqlalchemy.orm import sessionmaker from conf import settings #用户登陆函数
def auth():
'''
do the user login authentication
:return:
'''
count = 0
while count <3:#用户输入三次机会
username = input("\033[32;1mUsername:\033[0m").strip()
if len(username) ==0:continue
password = input("\033[32;1mPassword:\033[0m").strip()
if len(password) ==0:continue
user_obj = session.query(models.UserProfile).filter(models.UserProfile.username==username,
models.UserProfile.password==password).first()#从数据库中获取堡垒机用户信息
if user_obj:
return user_obj
else:
print("wrong username or password, you have %s more chances." %(3-count-1))
count +=1
else:
print_err("too many attempts.") #欢迎界面
def welcome_msg(user):
WELCOME_MSG = '''\033[32;1m
------------- Welcome [%s] login LittleFinger -------------
\033[0m'''% user.username
print(WELCOME_MSG) #写入数据库 日志
def log_recording(user_obj,bind_host_obj,logs):
'''
flush user operations on remote host into DB
:param user_obj:
:param bind_host_obj:
:param logs: list format [logItem1,logItem2,...]
:return:
'''
print("\033[41;1m--logs:\033[0m",logs)
session.add_all(logs)
session.commit() #开始函数
def start_session(argvs):
print('going to start sesssion ')
user = auth()#判断用户名 并返回用户对应信息
if user:
welcome_msg(user)#打印欢迎界面
#print(user.id)#用户ID
#print(user.bind_hosts)#绑定主机
#print(user.host_group)#所在组
#log_recording(user,user.bind_hosts,user.host_group,logs)
exit_flag = False#设定点 为假
while not exit_flag:#如果设定点 为假 说明登陆成功
if user.bind_hosts:#有绑定远程主机 打印远程主机
print('\033[32;1mz.\tungroupped hosts (%s)\033[0m' %len(user.bind_hosts) )
for index,group in enumerate(user.host_group):#打印当前用户所在组
print('\033[32;1m%s.\t%s (%s)\033[0m' %(index,group.group_name, len(group.bind_host)) ) print('(q)=quit')
choice = input("[%s]:" % user.username).strip()#开始获取输入的命令 if len(choice) == 0:continue#如果没有输入跳过
if choice == 'q':
exit_flag=True
#if choice=='exit': exit()#退出
if choice == 'z':#如果输入 z
print("------ Group: ungroupped hosts ------" )#输出所有的未分组的主机
for index,bind_host in enumerate(user.bind_hosts):
print(" %s.\t%s@%s(%s)"%(index,
bind_host.remote_user.username,#绑定的用户名
bind_host.host.hostname,#主机名
bind_host.host.ip,#IP地址
))
print("----------- END -----------" )
elif choice.isdigit():#如果是选择数字
choice = int(choice)
if choice < len(user.host_group):
print("------ Group: %s ------" % user.host_group[choice].group_name )
for index,bind_host in enumerate(user.host_group[choice].bind_host):#打印出选择组的包括的
print(" %s.\t%s@%s(%s)"%(index,
bind_host.remote_user.username,#绑定的用户名
bind_host.host.hostname,#主机名
bind_host.host.ip,#IP地址
))
print("----------- END -----------" ) #host selection
while not exit_flag:
user_option = input("[(b)back, (q)quit, select host to login]:").strip()
if len(user_option)==0:continue
if user_option == 'b':break
if user_option == 'q':
exit_flag=True
if user_option.isdigit():
user_option = int(user_option)
if user_option < len(user.host_group[choice].bind_host) :#查看分组所绑定的远程 主机
print('host:',user.host_group[choice].bind_host[user_option])
print('audit log:',user.host_group[choice].bind_host[user_option].audit_logs)
ssh_login.ssh_login(user,
user.host_group[choice].bind_host[user_option],
session,
log_recording)
else:
print("no this option..") #停止退出
def stop_server(argvs):
exit() #创建表结构
def syncdb(argvs):
print("Syncing DB....[创建所有表结构]")
models.Base.metadata.create_all(engine) #创建所有表结构 '''======创建四个基础表==== '''
#堡垒机用户添加
def create_users(argvs):
if '-f' in argvs:#判断参数 -f 是否存在
user_file = argvs[argvs.index("-f") +1 ]#获取文件位置
else:
print_err("invalid usage, should be:\ncreateusers -f <the new users file>",quit=True)
source = yaml_parser(user_file)#获取文件内容数据
if source:#如果获取成功
for key,val in source.items():
print(key,val)
obj = models.UserProfile(username=key,password=val.get('password'))#创建新数据
session.add(obj)
session.commit() #分组添加
def create_groups(argvs):
if '-f' in argvs:#判断参数 -f 是否存在
group_file = argvs[argvs.index("-f") +1 ]
else:
print_err("invalid usage, should be:\ncreategroups -f <the new groups file>",quit=True)
source = yaml_parser(group_file)#通过yaml 获取文件中的数据,
if source:
for key,val in source.items():
print(key,val)
obj = models.HostGroup(group_name=key)#创建一条新数据
if val.get('bind_hosts'):#
bind_hosts = bind_hosts_filter(val)#绑定的远程主机组合表
obj.bind_host = bind_hosts
if val.get('user_profiles'):#堡垒机用户
user_profiles = user_profiles_filter(val)#堡垒机用户
obj.user_profiles = user_profiles
session.add(obj)
session.commit() #远程主机添加
def create_hosts(argvs):
if '-f' in argvs:#判断参数 -f 是否存在
hosts_file = argvs[argvs.index("-f") +1 ]
else:
print_err("invalid usage, should be:\ncreate_hosts -f <the new hosts file>",quit=True)#退出函数
source = yaml_parser(hosts_file)#通过yaml 获取文件中的数据,
if source:#如果获取成功,不为空
for key,val in source.items():#进行数据的解析
print(key)
print(val)
obj = models.Host(hostname=key,ip=val.get('ip'), port=val.get('port') or 22)#port 端口默认为22
session.add(obj)#写入到数据库
session.commit()#关闭 确认写入 #创建远程主机用户
def create_remoteusers(argvs):
if '-f' in argvs:
remoteusers_file = argvs[argvs.index("-f") +1 ]
else:
print_err("invalid usage, should be:\ncreate_remoteusers -f <the new remoteusers file>",quit=True)
source = yaml_parser(remoteusers_file)#通过yaml 获取文件中的数据,
if source:
for key,val in source.items():#进行数据的解析
print(key,val)
obj = models.RemoteUser(username=val.get('username'),auth_type=val.get('auth_type'),password=val.get('password'))
session.add(obj)#写入数据库
session.commit() '''====远程主机与远程主机用户组合表====='''
##远程主机用户名密码与远程主机组合绑定 关联 到堡垒机用户
def create_bindhosts(argvs):
if '-f' in argvs:
bindhosts_file = argvs[argvs.index("-f") +1 ]
else:
print_err("invalid usage, should be:\ncreate_hosts -f <the new bindhosts file>",quit=True)
source = yaml_parser(bindhosts_file)#通过yaml 获取文件中的数据,
if source:
for key,val in source.items():
print(key,val)
host_obj = session.query(models.Host).filter(models.Host.hostname==val.get('hostname')).first()#获取对应主机数据
assert host_obj#断言 当前主机一定要存在才能往下执行
for item in val['remote_users']:#输出存在的远程主机用户
print(item )
assert item.get('auth_type')#断言 一定要存在才能往下执行
if item.get('auth_type') == 'ssh-passwd':#判断ssh连接类型 从数据库选出合条件的数据
remoteuser_obj = session.query(models.RemoteUser).filter(
models.RemoteUser.username==item.get('username'),
models.RemoteUser.password==item.get('password')
).first()#获取主机数据 返回对象
else:
remoteuser_obj = session.query(models.RemoteUser).filter(
models.RemoteUser.username==item.get('username'),
models.RemoteUser.auth_type==item.get('auth_type'),
).first()
if not remoteuser_obj:#如果远程主机用户不存在
print_err("RemoteUser obj %s does not exist." % item,quit=True )
bindhost_obj = models.BindHost(host_id=host_obj.id,remote_user_id=remoteuser_obj.id)#创建一条新数据
session.add(bindhost_obj)
#for groups this host binds to
if source[key].get('groups'):#如果有分组标志
#获取分组信息
group_objs = session.query(models.HostGroup).filter(models.HostGroup.group_name.in_(source[key].get('groups') )).all()
assert group_objs#断言 分组一定要存在才能往下执行
print('groups:', group_objs)
bindhost_obj.host_groups = group_objs#主机加到分组
#for user_profiles this host binds to
if source[key].get('user_profiles'):#如果有堡垒机用户标志
#获取堡垒机用信息
userprofile_objs = session.query(models.UserProfile).filter(models.UserProfile.username.in_(
source[key].get('user_profiles')
)).all()
assert userprofile_objs#断言 堡垒机用户一定要存在才能往下执行
print("userprofiles:",userprofile_objs)
bindhost_obj.user_profiles = userprofile_objs#主机与堡垒机用户绑定
#print(bindhost_obj)
session.commit() #远程主机组合表查看
def bind_hosts_filter(vals):#远程主机组合表查看
print('**>',vals.get('bind_hosts') )
bind_hosts = session.query(models.BindHost).filter(models.Host.hostname.in_(vals.get('bind_hosts'))).all()
if not bind_hosts:
print_err("none of [%s] exist in bind_host table." % vals.get('bind_hosts'),quit=True)
return bind_hosts #堡垒机用户查看
def user_profiles_filter(vals):
user_profiles = session.query(models.UserProfile).filter(models.UserProfile.username.in_(vals.get('user_profiles'))).all()
if not user_profiles:
print_err("none of [%s] exist in user_profile table." % vals.get('user_profiles'),quit=True)
return user_profiles #查看用户日志
def audit(argvs):
if '-n' in argvs:
user_name = argvs[argvs.index("-n") +1 ]#获取要查看的用户名
else:
print_err("invalid usage, should be:\n输入参数 -n <用户名/user_name >",quit=True)
print(user_name)
user_obj = session.query(models.UserProfile).filter(models.UserProfile.username==user_name).first()#取到
print(user_obj.id)
log_obj = session.query(models.AuditLog).filter(models.AuditLog.user_id==user_obj.id).all()
for i in log_obj:
print('堡垒机用户:【%s】,远程主机【%s】,远程用户:【%s】命令:【%s】,日期:【%s】'%(i.user_profile,i.bind_host.host,i.bind_host.remote_user,i.cmd,i.date))
input('========')
|- - -share/#添加堡垒机用户\远程主机\分组\远程主机用户 目录
| |- - -examples/#文件目录
| |- - -new_bindhosts.yml/#远程主机用户与远程主机 组合表(组合表与 分组)(堡垒机用户与组合表) 创建 示例
 bind0:
hostname: ubuntu test
remote_users:
- user0:
username: root
auth_type: ssh-passwd
password: root
groups:
- test_group
user_profiles:
- uge3
- alex bind1:
hostname: server1
remote_users:
- user1:
username: root
auth_type: ssh-key
#password: 123
- user0:
username: root
auth_type: ssh-passwd
password: root
- user4:
username: calmyan
auth_type: ssh-passwd
password: yjj
groups:
- bj_group
user_profiles:
- uge3 bind2:
hostname: server2
remote_users:
- user1:
username: alex
auth_type: ssh-passwd
password: alex3714
groups:
- bj_group
- sh_group
user_profiles:
- rain
|              |- - -new_groups.yml/#分组创建 示例( 堡垒机用户与 分组)
 bj_group:
user_profiles:
- alex
- uge3 sh_group:
user_profiles:
- jack
- alex
- rain
- uge3
test_group:
user_profiles:
- uge3
|              |- - -new_hosts.yml/#远程主机创建 示例
 ubuntu test:
ip: 192.168.11.50
port: 22 server1:
ip: 192.168.11.51 server2:
ip: 10.4.4.22
port: 30000
|              |- - -new_remoteusers.yml/#远程主机用户创建 示例
 user0:
auth_type: ssh-passwd
username: root
password: root user1:
auth_type: ssh-passwd
username: root
password: alex!34321 user2:
auth_type: ssh-key
username: root
#password: abc!23 user3:
auth_type: ssh-passwd
username: alex
password: alex3714 user4:
auth_type: ssh-passwd
username: calmyan
password: yjj
|              |- - -new_user.yml/#堡垒机用户机创建 示例
 alex:
password: alex123
uge3:
password: uge3 jack:
password: jack123 rain:
password: rain123