settings.py

INSTALLED_APPS = [...'app01',   # 注册app
]
MIDDLEWARE = [
...
# 'django.middleware.csrf.CsrfViewMiddleware',...
]
ALLOWED_HOSTS = ["*"]    # Linux下启动用0.0.0.0 添加访问的host即可在Win7下访问STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)  # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [...'DIRS': [os.path.join(BASE_DIR, 'templates')],
]
# 自定义账户生效
AUTH_USER_MODEL = "app01.UserProfile"   # app名.表名# 监测脚本
SESSION_TRACKER_SCRIPT = "%s/backend/session_trackor.sh" %BASE_DIR
AUDIT_LOG_PATH = "%s/logs/audit" % BASE_DIR

user_enterpoint.py

import getpass
import os
import hashlib, time
import subprocess
from django.contrib.auth import authenticate# 用户输入命令行端交互入口
class UserPortal(object):def __init__(self):self.user = None# 用户交互认证def user_auth(self):retry_count = 0while retry_count < 3:username = input("Username:").strip()if (len(username) == 0): continue
# password = getpass.getpass("Password:").strip()password = input("Password:").strip()if (len(password) == 0):print("password must not be null")continueuser = authenticate(username=username, password=password)if(user):self.user = userprint("welcome login...")returnelse:print("invalid password or username...")retry_count += 1else:exit("Too many atttempts....")# 交互函数def interactive(self):self.user_auth()print("验证完成...")if self.user:exit_flag = Falsewhile not exit_flag:# 显示用户可以访问的用户组信息信息host_groups = self.user.host_groups.all()host_groups_count = self.user.host_groups.all().count()print('----------------------------------------------------------------------')print("host_groups: ", host_groups)print('host_groups_count:', host_groups_count)print('----------------------------------------------------------------------')# 记录主机组所关联的全部主机信息for index, hostGroup in enumerate(host_groups):# 0, Webserver【Host Count: 2】print("%s. %s【Host Count: %s】" % (index, hostGroup.name, hostGroup.bind_hosts.all().count()))# 用户直接关联的主机信息# 1. Ungrouped Hosts[1]# Py特性,这里的index并未被释放,在循环完成后index值还存在,且值为最后循环的最后一个值print("%s. Ungrouped Hosts[%s]" % (index + 1, self.user.bind_hosts.select_related().count()))# 用户选择需要访问的组信息user_input = input("Please Choose Group:").strip()if len(user_input) == 0:print('please try again...')continueif user_input.isdigit():user_input = int(user_input)# 在列表范围之内if user_input >= 0 and user_input < host_groups_count:selected_group = self.user.host_groups.all()[user_input]# 选中了未分组的那组主机elif user_input == self.user.host_groups.all().count():# 之所以可以这样,是因为self.user里也有一个bind_hosts,跟HostGroup.bind_hosts指向的表一样selected_group = self.user  # 相当于更改了变量的值,但期内都有bind_hosts的属性,所以循环是OK的else:print("invalid host group")continueprint('selected_group:', selected_group.bind_hosts.all())print('selected_group_count:', selected_group.bind_hosts.all().count())while True:for index, bind_host in enumerate(selected_group.bind_hosts.all()):print("%s. %s(%s user:%s)" % (index,bind_host.host.hostname,bind_host.host.ip_addr,bind_host.host_user.username))user_input2 = input("Please Choose Host:").strip()if len(user_input2) == 0:print('please try again...')continueif user_input2.isdigit():user_input2 = int(user_input2)if user_input2 >= 0 and user_input2 < selected_group.bind_hosts.all().count():selected_bindhost = selected_group.bind_hosts.all()[user_input2]print("--------------start logging -------------- ", selected_bindhost)md5_str = hashlib.md5(str(time.time()).encode()).hexdigest()login_cmd = 'sshpass  -p {password} /usr/local/openssh7/bin/ssh {user}@{ip_addr}  -o "StrictHostKeyChecking no" -Z {md5_str}'.format(password=selected_bindhost.host_user.password,user=selected_bindhost.host_user.username,ip_addr=selected_bindhost.host.ip_addr,md5_str=md5_str)print('login_cmd:', login_cmd)# 这里的ssh_instance在subprocess的run执行完之前是拿不到的# 因为run会进入终端界面# 问题来了? 怎么拿到进程PID进行strace呢?  重启一个监测进程# start session tracker scriptsession_tracker_script = settings.SESSION_TRACKER_SCRIPTtracker_obj = subprocess.Popen("%s %s" % (session_tracker_script, md5_str), shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE,# 这个cwd命名式指定python运行的路径的cwd=settings.BASE_DIR)# time.sleep(15)   # 测试网络延时情况# create session logmodels.SessionLog.objects.create(user=self.user, bind_host=selected_bindhost,session_tag=md5_str)ssh_instance = subprocess.run(login_cmd, shell=True)print("------------logout---------")print("session tracker output", tracker_obj.stdout.read().decode(),tracker_obj.stderr.read().decode())  # 不解码显示的是二进制print("--------------end  logging ------------- ")# 退出循环if user_input2 == 'b':breakif __name__ == '__main__':os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CityHunter.settings")import djangodjango.setup()from django.conf import settings
from app01 import modelsportal = UserPortal()portal.interactive()

admin.py

from django.contrib import admin
from django import forms
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashFieldfrom app01 import models
class UserCreationForm(forms.ModelForm):"""A form for creating new users. Includes all the requiredfields, plus a repeated password."""password1 = forms.CharField(label='Password', widget=forms.PasswordInput)password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)class Meta:model = models.UserProfilefields = ('email', 'name')def clean_password2(self):# Check that the two password entries matchpassword1 = self.cleaned_data.get("password1")password2 = self.cleaned_data.get("password2")if password1 and password2 and password1 != password2:raise forms.ValidationError("Passwords don't match")return password2def save(self, commit=True):# Save the provided password in hashed formatuser = super(UserCreationForm, self).save(commit=False)user.set_password(self.cleaned_data["password1"])if commit:user.save()return userclass UserChangeForm(forms.ModelForm):"""A form for updating users. Includes all the fields onthe user, but replaces the password field with admin'spassword hash display field."""password = ReadOnlyPasswordHashField()class Meta:model = models.UserProfilefields = ('email', 'password', 'name', 'is_active', 'is_superuser')def clean_password(self):# Regardless of what the user provides, return the initial value.# This is done here, rather than on the field, because the# field does not have access to the initial valuereturn self.initial["password"]class UserProfileAdmin(BaseUserAdmin):# The forms to add and change user instancesform = UserChangeFormadd_form = UserCreationForm# The fields to be used in displaying the User model.# These override the definitions on the base UserAdmin# that reference specific fields on auth.User.list_display = ('email', 'name', "is_active", 'is_superuser')list_filter = ('is_superuser',) # 不添加会报错,因为BaseAdmin里面有一个list_filter字段,不覆盖会报错fieldsets = ((None, {'fields': ('email', 'password')}),('Personal', {'fields': ('name',)}),('Permissions', {'fields': ('is_superuser',"is_active","bind_hosts","host_groups","user_permissions","groups")}),)# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin# overrides get_fieldsets to use this attribute when creating a user.add_fieldsets = ((None, {'classes': ('wide',),'fields': ('email', 'name', 'password1', 'password2')}),)search_fields = ('email',)ordering = ('email',)filter_horizontal = ("bind_hosts","host_groups","user_permissions","groups")class HostUserAdmin(admin.ModelAdmin):list_display = ('username','auth_type','password')class SessionLogAdmin(admin.ModelAdmin):list_display = ('id','session_tag','user','bind_host','date')admin.site.register(models.UserProfile, UserProfileAdmin)
admin.site.register(models.Host)
admin.site.register(models.HostGroup)
admin.site.register(models.HostUser,HostUserAdmin)
admin.site.register(models.BindHost)
admin.site.register(models.IDC)
admin.site.register(models.SessionLog,SessionLogAdmin)

models.py

from django.db import models
from django.contrib.auth.models import (BaseUserManager, AbstractBaseUser,PermissionsMixin
)
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
# Create your models here.class Host(models.Model):"""主机信息"""hostname = models.CharField(max_length=64)ip_addr = models.GenericIPAddressField(unique=True)port = models.PositiveIntegerField(default=22)idc = models.ForeignKey("IDC", on_delete=True)enabled = models.BooleanField(default=True)def __str__(self):return "%s(%s)"%(self.hostname,self.ip_addr)class IDC(models.Model):"""机房信息"""name = models.CharField(max_length=64,unique=True)def __str__(self):return self.nameclass HostGroup(models.Model):"""主机组"""name = models.CharField(max_length=64,unique=True)bind_hosts = models.ManyToManyField("BindHost",blank=True,)def __str__(self):return self.nameclass UserProfileManager(BaseUserManager):def create_user(self, email, name, password=None):"""Creates and saves a User with the given email, date ofbirth and password."""if not email:raise ValueError('Users must have an email address')user = self.model(email=self.normalize_email(email),name=name,)user.set_password(password)self.is_active = Trueuser.save(using=self._db)return userdef create_superuser(self,email, name, password):"""Creates and saves a superuser with the given email, date ofbirth and password."""user = self.create_user(email,password=password,name=name,)user.is_active = Trueuser.is_superuser = True#user.is_admin = Trueuser.save(using=self._db)return userclass UserProfile(AbstractBaseUser,PermissionsMixin):"""堡垒机账号"""email = models.EmailField(verbose_name='email address',max_length=255,unique=True,null=True)password = models.CharField(_('password'), max_length=128,help_text=mark_safe('''<a href='password/'>修改密码</a>'''))name = models.CharField(max_length=32)is_active = models.BooleanField(default=True)#is_admin = models.BooleanField(default=False)bind_hosts = models.ManyToManyField("BindHost",blank=True)host_groups = models.ManyToManyField("HostGroup",blank=True)objects = UserProfileManager()USERNAME_FIELD = 'email'REQUIRED_FIELDS = ['name']def get_full_name(self):# The user is identified by their email addressreturn self.emaildef get_short_name(self):# The user is identified by their email addressreturn self.emaildef __str__(self):              # __unicode__ on Python 2return self.email  @propertydef is_staff(self):"Is the user a member of staff?"# Simplest possible answer: All admins are staffreturn self.is_activeclass HostUser(models.Model):"""主机登录账户"""auth_type_choices = ((0,'ssh-password'),(1,'ssh-key'))auth_type = models.SmallIntegerField(choices=auth_type_choices,default=0)username = models.CharField(max_length=64)password = models.CharField(max_length=128,blank=True,null=True)def __str__(self):return "%s:%s" %(self.username,self.password)class Meta:unique_together = ('auth_type','username','password')class BindHost(models.Model):"""绑定主机和主机账号"""host = models.ForeignKey("Host", on_delete=True)host_user = models.ForeignKey("HostUser", on_delete=True)def __str__(self):return "%s@%s"%(self.host,self.host_user)class Meta:unique_together = ('host', 'host_user')
class SessionLog(models.Model):"""存储session日志"""# 堡垒机用户  主机信息   唯一标示user = models.ForeignKey("UserProfile", on_delete=True)bind_host = models.ForeignKey("BindHost", on_delete=True)session_tag = models.CharField(max_length=128,unique=True)date = models.DateTimeField(auto_now_add=True)def __str__(self):return self.session_tag

更改db文件的权限,方便sessioni日志的记录

omc@omc-virtual-machine:~$  cd CityHunter/
omc@omc-virtual-machine:~$  chmod 777 db.sqlite3  【更改文件属组为cityhunber也可以】

上传Django项目到服务器并解压

omc@omc-virtual-machine:~$ unzip CityHunter.zip    【解压Django的zip包】

创建登录堡垒机服务器[Ubuntun]的账户

Ubuntu上创建ciythunber用户:

omc@omc-virtual-machine:~$ sudo adduser cityhunteromc@omc-virtual-machine:~$ tail -1 /etc/passwd

cityhunter用户增加sudo权限

root@omc-virtual-machine:~# vim /etc/sudoers
root@omc-virtual-machine:~# visudo -c
root@omc-virtual-machine:~# grep 'cityhunter' /etc/sudoers

设置登录堡垒机服务器后自动执行user_enterpoint.py脚本且执行完成后自动退出服务器

cityhunter@omc-virtual-machine:~$ tail -3 /home/cityhunter/.bashrc    【仅添加3行内容】
# for cityhunter auditing: after user logged auto execute this python file
/usr/bin/python3 /home/omc/CityHunter/user_enterpoint.py
logout

另:新创建的用户没有Django的环境变量,需要手动添加才能执行脚本成功

Ps:  如果环境上有DJango环境变量则不用执行如下操作

查看omc用户的Django变量所在的位置

omc@omc-virtual-machine:~/CityHunter$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path

新创建的cityhunter用户添加py的环境变量

cityhunter@omc-virtual-machine:~$ pip3 install pika   【仅仅是为了添加Py变量方便】

查看新用户cityhunter的Py环境变量

cityhunter@omc-virtual-machine:~$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path

复制omc用户下的Django文件到cityhunter用户下

omc@omc-virtual-machine:~/CityHunter$sudo cp -rf /home/omc/.local/lib/python3.5/site-packages/ /home/cityhunter/.local/lib/python3.5/

更改Django文件属组,让cityhunter用户可以访问

cityhunter用户下查看属组:
cityhunter@omc-virtual-machine:~$ id cityhunter        【cityhunter用户下查看用户属组】
uid=1001(cityhunter) gid=1001(cityhunter) groups=1001(cityhunter)

cmc用户下更改属组[服务器是omc服务器]

omc@omc-virtual-machine:~/CityHunter$ sudo chown cityhunter:cityhunter  -R /home/cityhunter/.local/ 

Ubuntu下cityhunter用户执行命令:

cityhunter@omc-virtual-machine:~/CityHunter$ python3 /home/omc/CityHunter/user_enterpoint.py
Username:ftl@126.com
Password:cnpXXX
welcome login...
验证完成...
----------------------------------------------------------------------
host_groups:  <QuerySet [<HostGroup: Webserver>]>
host_groups_count: 1
----------------------------------------------------------------------
0. Webserver【Host Count: 2】
1. Ungrouped Hosts[1]
Please Choose Group:0
selected_group: <QuerySet [<BindHost: Ubuntu(192.168.25.110)@omc:lem600XXX>, <BindHost: Redhat(192.168.25.133)@root:cnpXXX>]>
selected_group_count: 2
0. Ubuntu(192.168.25.110 user:omc)
1. Redhat(192.168.25.133 user:root)
Please Choose Host:1
--------------start logging --------------  Redhat(192.168.25.133)@root:cnp200XXX
login_cmd: sshpass  -p cnp200XXX ssh root@192.168.25.133  -o "StrictHostKeyChecking no"
Last login: Mon May  7 07:44:00 2018 from 192.168.25.110
[root@localhost ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              18G  3.3G   14G  20% /
tmpfs                 250M     0  250M   0% /dev/shm
/dev/sda1             291M   32M  245M  12% /boot

Linux服务器[Ubuntu]下DJango的运行:

后台启动Django:
omc@omc-virtual-machine:~$ cd /home/omc/CityHunter/
omc@omc-virtual-machine:~/CityHunter$ python3 manage.py runserver 0.0.0.0:9000
omc@omc-virtual-machine:~$ netstat -an|grep 9000 

前台Win7访问:

远程使用cityhunter用户登录结果演示:

终端登录:

问题记录

问题现象1:

django.core.exceptions.ImproperlyConfigured: Requested setting AUTHENTICATION_BACKENDS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings

我们在自己的Py脚本里面调用Django的数据库,没有添加环境变量导致验证失败【参考manage.py,添加环境变量解决】

问题解决:

后台结果:

问题现象2:

django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

问题定位:

问题解决:

1. 添加Django的环境变量后导入DJango的东西

2. 删除导入信息[不实际]

转载于:https://www.cnblogs.com/ftl1012/p/9459306.html

审计系统---堡垒机项目之用户交互程序开发相关推荐

  1. 审计系统---堡垒机项目之表结构设计

    [更多参考] https://github.com/317828332/CrazyEye 缺点: 界面丑陋, 只能追踪命令,命令的解析还不是很完善,不能明了的展示 对于文件的上传[rz],下载[sz] ...

  2. 审计系统---堡垒机python下ssh的使用

    堡垒机python下ssh的使用 [堡垒机更多参考]http://www.cnblogs.com/alex3714/articles/5286889.html [paramiko的Demo实例]htt ...

  3. c语言字符串用for语句去重,python简介、第一个python程序、变量、字符编码、用户交互程序、if...else、while、for...

    也愿大家永葆初心-- 已识乾坤大,犹怜草木青. 一.python简介 首先,我们普及一下编程语言的基础知识.用任何编程语言来开发程序,都是为了让计算机干活,比如下载一个MP3,编写一个文档等等,而计算 ...

  4. 常见安全设备总结(IDS、IPS、上网行为管理、网闸、漏扫、日志审计、数据库审计、堡垒机等)

    常见安全设备总结(IDS.IPS.上网行为管理.网闸.漏扫.日志审计.数据库审计.堡垒机等) 一.网络结构 二.防火墙.IPS 1.防火墙 2.IPS 三.上网行为管理.网闸 1.上网行为管理 2.网 ...

  5. php和python交互-Python如何实现简单的用户交互程序(示例)

    本篇文章给大家带来的内容是关于Python如何实现简单的用户交互程序(示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 我们经常使用的程序都会有与用户交互的程序,比如网页的登录, ...

  6. 齐治堡垒机_任意用户登录漏洞

    fofa查询语法 app="齐治科技-堡垒机" 漏洞复现 漏洞POC为 http://xxx.xxx.xxx.xxx/audit/gui_detail_view.php?token ...

  7. 注释和简单用户交互程序

    一.注释 Python的注释很简单,有两种方法: 1. #这是注释 改方法会注释掉该行"#"号后面的所有内容,注释掉的内容不会被运行 2. 1 '''这是注释 2 这是注释 3 这 ...

  8. uni-app实战之社区交友APP(14)用户交互模块开发

    文章目录 前言 一.修改资料模块开发 1.编辑头像API开发 2.修改用户信息API开发 3.修改密码API接口开发 二.黑名单模块开发 1.数据表设计 2.加入黑名单API开发 3.移出黑名单API ...

  9. 微信小程序开发教程:项目二微信小程序开发基础 课后习题

    <微信小程序开发教程>主编/黄寿孟 易芳 陶延涛 湖南大学出版社 目录 一.单选题 二.多选题 三.判断题 四.填空题 五.简答题 1.请简单描述页面样式的单位rpx与px的关系. 2.简 ...

  10. 顾客点餐系统(1)-------整体项目目标+用户数据表的操作

    项目初心:我们可以让用户更方便的进行使用手机进行在线点菜 一:针对用户自主点餐: 基本功能: 1)注册登录,退出登录 2)主页面中可以看到当前店家的菜品列表(菜名,价格,是否要进行选餐), 3)点击要 ...

最新文章

  1. mysql 导入数据 1215_12、mysql导入数据
  2. “ yield”关键字有什么作用?
  3. 在Tomcat上挂载预下载文件的方法
  4. Hive 1.2.1SparkSqoop安装指南
  5. flutter 如何判断在哪个页面_如何判断初中英语辅导哪个更好呢?
  6. OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
  7. excanvas让canvas兼容ie7,8
  8. 最流行的 RESTful API 要怎么设计?
  9. 实数系的连续性的含义
  10. 万物互联-stm32单片机简介、烧录、编程及其项目环境搭建
  11. 2021-2027全球与中国充电辊市场现状及未来发展趋势
  12. 用excel函数COUNTIF实现两列数据对比找出不同数据
  13. html5时钟在图片上画指针,HTML5使用canvas元素绘制指针式动画时钟_网页代码站(www.webdm.cn)...
  14. LeetCode 刷题: Fizz Buzz
  15. 《R语言与数据挖掘》③-①使用R语言进行中文分词
  16. 获取高匿代理ip的想法思路
  17. DDD 实战 (11):冲刺 1 代码 TDD 实现之道
  18. alc236黑苹果驱动_黑苹果核心显卡驱动教程
  19. android swstnw cn,Android应用开发之ubuntu14.04编译ijkplayer备忘
  20. python numpy安装失败_Mac下安装Python的numpy库失败的解决方法

热门文章

  1. Java/大数据常见面试
  2. 2011年美国大学招生广告
  3. 软工网络15团队作业4——Alpha阶段敏捷冲刺之Scrum 冲刺博客(Day1)
  4. IOS开发之协议和代理
  5. IE11主页被篡改解决方法
  6. C#基础 连接数据库
  7. Maven Helper 插件介绍
  8. 90后在虚拟世界建国风园林,完美融合数字艺术与传统诗词
  9. C解决duplicate symbol
  10. marvell raid linux,佳能 RAID Console 驱动程序下载-更新佳能软件(磁盘阵列控制器)