返回介绍

14.5 服务器端功能设计

发布于 2024-01-29 22:54:22 字数 4765 浏览 0 评论 0 收藏 0

14.5.1 Django配置

安全审计功能作为OMServer的一个功能扩展,需要Web服务器端开发框架(Django)同样做些变更来支持新增的功能。由于该功能作为项目的一个App,因此,第一步需要创建一个App,操作如下:

# cd /data/www/OMserverweb
# python manage.py startapp omaudit

在创建的omaudit目录中修改urls.py,添加App的URL映射规则,内容如下:

from django.conf.urls.defaults import *
urlpatterns = patterns('omaudit.views',
  (r'^$','index'),
  (r'omaudit_pull/$','omaudit_pull'),  #映射到omaudit_pull方法,实现客户端数据接收
  (r'omaudit_run/$','omaudit_run'),   #映射到omaudit_run方法,实现前端实时查询
)

修改App的models.py,实现与数据库的关系映射,内容如下:

from django.db import models
# Create your models here.
class ServerHistory(models.Model):
  id = models.IntegerField(primary_key=True, db_column='ID') # Field name made lowercase.
  history_id = models.IntegerField
  history_ip = models.CharField(max_length=45)
  history_user = models.CharField(max_length=45)
  history_datetime = models.DateTimeField
  db_datetime = models.DateTimeField
  history_command = models.CharField(max_length=765)
  class Meta:
     db_table = u'server_history'

如果数据库结构已经存在,可以通过python manage.py inspectdb命令来生成models代码。

最后修改项目settings.py,注册该App名称,内容如下:

INSTALLED_APPS = (
… …
  # 'django.contrib.admindocs',
  'public',
  'autoadmin',
  'omaudit',   #添加此行,注册该App
)

14.5.2 功能实现方法

服务器端提供了两个关键视图方法,分别实现前端实时展示(omaudit_run)及数据接收(omaudit_pull),下面针对两个方法进行说明。

(1)前端实时展示(omaudit_run)方法

关于前端数据实时展示的实现原理,通过前端JavaScript的setInterval方法实现定时函数调用,首次请求默认返回ID倒序最新5条记录,并记录下LastID(最新记录ID),后面的定时调用将传递LastID参数,数据库查询条件是“ID>LastID”,从而达到实时获取最新记录的目的,同时也支持选择主机来作为过滤条件,功能实现流程图见图14-5。

图14-5 前端数据展示流程图

omaudit_run方法实现源码如下:

"""
=事件任务前端展示方法
"""
def omaudit_run(request):
  if not 'LastID' in request.GET:   #获取上次查询到的最新记录ID
     LastID=""
  else:
     LastID=request.GET['LastID']
  if not 'hosts' in request.GET:   #获取选择的主机地址信息
     Hosts=""
  else:
     Hosts=request.GET['hosts']
  ServerHistory_string=""
  host_array=target_host(Hosts,"IP").split(';')   #调用target_host方法过滤出IP地址
  if LastID=="0":    #符合第一次提交条件,查询不加“id>LastID”条件,反之
     if Hosts=="":   #符合没有选择主机条件,查询不加“history_ip in host_array”
                #条件,反之
        ServerHistoryObj = ServerHistory.objects \
        .order_by('-id')[:5]
     else:
        ServerHistoryObj = ServerHistory.objects \
        .filter(history_ip__in=host_array).order_by('-id')[:5]
  else:
     if Hosts=="":
        ServerHistoryObj = ServerHistory.objects \
        .filter(id__gt=LastID).order_by('-id')
     else:
        ServerHistoryObj = ServerHistory.objects \
        .filter(id__gt=LastID,history_ip__in=host_array).order_by('-id')
  lastid=""
  i=0
  for e in ServerHistoryObj:   #遍历查询结果,返回给前端
     if i==0:
        lastid=e.id
     ServerHistory_string+="<font color=#cccccc>"+e.history_ip+ \
     "</font> ; ;\t"+ e.history_user+" ; ;\t"+ \
     str(e.db_datetime)+"\t # <font color=#ffffff>"+e.history_command+"</font>*"
     i+=1
  ServerHistory_string+="@@"+str(lastid)   #通过“@@”字符分隔事件记录与lastid,
                              #前端拆分
  return HttpResponse(ServerHistory_string)

(2)数据接收(omaudit_pull)方法

数据接收方法相对比较简单,即将接收到的信息直接入库,实现的源码如下:

"""
=事件任务pull方法
"""
def omaudit_pull(request):
  if request.method == 'GET':   #校验HTTP(GET)请求参数合法性
     if not request.GET.get('history_id', ''):
        return HttpResponse("history_id null")
     if not request.GET.get('history_ip', ''):
        return HttpResponse("history_ip null")
     if not request.GET.get('history_user', ''):
        return HttpResponse("history_user null")
     if not request.GET.get('history_datetime', ''):
        return HttpResponse("history_datetime null")
     if not request.GET.get('history_command', ''):
        return HttpResponse("history_command null")
     history_id=request.GET['history_id']   #获取HTTP请求参数值
     history_ip=request.GET['history_ip']
     history_user=request.GET['history_user']
     history_datetime=request.GET['history_datetime']
     history_command=request.GET['history_command']
     historyobj = ServerHistory(history_id=history_id, \   #数据入库(insert)
        history_ip=history_ip, \
        history_user=history_user, \
        history_datetime=history_datetime, \
        history_command=history_command)
     try:
        historyobj.save
     except Exception,e:
        return HttpResponse("入库失败,请与管理员联系!"+str(e))
     Response_result="OK"   #输出“OK”字符作为成功标志
     return HttpResponse(Response_result)
  else:
     return HttpResponse("非法提交!")

当然,如接入的集群过于庞大,服务器端数据库会逐步形成瓶颈,主机审计信息入库会出现一定延时,影响Linux用户操作体验,一个可行的方案是采用信息异步入库,即先将信息写入本地,再通过上报程序后台提交信息,用户将无感知。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文