PearAdmin二次开发之防火墙封禁工具——一键部署篇

目录

一、创建目录和菜单

二、前台页面设计

三、后台代码设计

3.1 引入外部文件

3.2 创建主页路由

3.3 日志处理代码

3.4 一键部署后端执行代码

四、测试验证

4.1 主页面测试

4.2 策略冲突测试

4.3 防火墙本地日志验证

4.4 防护墙拦截策略部署成功


       本篇将实现防火墙拦截策略一键部署功能,新建的拦截策略将自动调整至策略顶部,拦截策略源地址为Deny_Group_Set,其成员为基于时间创建的动态地质组Deny_Group_时间戳,后续所有需要拦截的IP地址将追加至动态地质组。

一、创建目录和菜单

通过PearAdmin的【系统管理】-【权限管理】来创建护网自动化目录

在【护网自动化】目录下创建【一键部署】菜单,并设置权限标识和路径。

刷新主页面后左侧导航树将会出现新创建的目录和菜单

二、前台页面设计

在项目【PearAdmin】-【templates】-【system】下创建【huwang】目录,在该目录下新建deploy.html文件。

前端页面代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>拦截策略部署</title>
    {% include 'system/common/header.html' %}
</head>
<body class="pear-container">
<div class="layui-card">
    <div class="layui-card-body ">
        <blockquote class="layui-elem-quote">
            拦截策略部署:防火墙一键拦截策略部署功能将在防火墙上新增一条全局的拦截策,同时将策略移至策略的顶端;该策略实现所有进接口(安全域)至所有出接口(安全域)的恶意源地址的所有协议通信将被拦截。
        </blockquote>
    </div>
</div>
<div class="layui-card">
	<fieldset class="layui-elem-field layui-field-title">
		<legend>拦截策略部署</legend>
	</fieldset>
	<div class="layui-card-body ">
		<form class="layui-form" action="">
			<div class="layui-form-item">
                <label class="layui-form-label">防火墙</label>
				<div class="layui-input-inline">
					<select name="firewall" lay-verify="required" lay-search>
						<option value=""></option>
						{% for key in device %}
						<option value={
           {key}}>{
           { device[key] }}</option>
						{% endfor %}
					</select>
				</div>
                <label class="layui-form-label">策略ID</label>
                <div class="layui-input-inline">
                    <input type="text" name="policyid" placeholder="请输入策略ID" value="1000000"
                           class="layui-input" lay-verify="required|number">
                </div>
                <div class="layui-input-inline">
                    <button class="layui-btn layui-btn-md" lay-submit lay-filter="deploy" >提交</button>
                    <button class="layui-btn layui-btn-md" type="reset" >取消</button>
                </div>
            </div>
		</form>
	</div>
</div>
<div class="layui-card">
    <fieldset class="layui-elem-field layui-field-title">
        <legend>部署日志</legend>
    </fieldset>
    <div class="layui-card-body">
        <table lay-filter="log-table"></table>
    </div>
</div>
</body>
{% include 'system/common/footer.html' %}
<script>
    layui.use(['table',  'form', 'jquery', 'popup'], function(){
        let table = layui.table,
            popup = layui.popup,
            form = layui.form,
            $ = layui.$;

        form.on('submit(deploy)', function(data){
            // 显示加载中提示
            var loadingIndex = layer.load(1, {
                shade: [0.1, '#fff'] //0.1透明度的白色背景
            });

            $.ajax({
                url: "/system/huwang/exec_deploy",
                type: "post",
                data: data.field,
                success: function(result){
                    layer.close(loadingIndex);  // 关闭加载提示

                    if (result.success) {
                        // 成功提示并刷新页面
                        layer.msg(result.msg, {icon: 1,time: 2000,title: '成功'
                        }, function(){
                            location.reload();  // 弹框关闭后刷新页面
                        });
                    } else {
                        // 失败提示
                        layer.msg(result.msg, {icon: 2,time: 3000,title: '失败'
                        });
                    }
                },
                error: function(xhr, status, error){
                    layer.close(loadingIndex);  // 关闭加载提示
                    layer.msg(`接口错误: ${status} ${error}`, {icon: 2,time: 3000,title: '错误'});
                }
            });
            return false;  // 阻止表单提交
        });

        let cols = [
            [
                {title: '时间', field: 'timestamp', align: 'center', width: 280},  // 时间需较宽
                {title: '进程名', field: 'logger_name', align: 'center', width: 280},
                {title: '级别', field: 'level', align: 'center', width: 100},
                {title: '内容', field: 'message', align: 'left',}  // 内容列用minWidth
            ]
        ];

        table.render({
            elem: '#log-table',
            url: '/system/huwang/deploy_log',
            page:{limit: 10,limits:[10,30,50]},
            cols: cols,
            skin: 'line',
            text: {none: '暂无设备信息'},
        })
    });
</script>

</html>

三、后台代码设计

在项目【PearAdmin】-【applications】-【view】目录下创建huwang.py文件实现后台处理。

3.1 引入外部文件

from flask import Blueprint, render_template, request
from applications.common.utils.http import table_api, fail_api, success_api
from applications.common.utils.rights import authorize
from applications.common.utils.validate import str_escape
from applications.common.utils.ip_check import ip_check
from applications.common.utils.temporary_ip_check import temporary_ip_check
from applications.common.utils.logging_setup import setup_logger
from applications.common.utils.fortigate_firewall import FortiGateManager
from applications.extensions import db
from applications.models import Resources, Hwlog


bp = Blueprint('huwang', __name__, url_prefix='/huwang')

3.2 创建主页路由

# 拦截策略部署
@bp.get('/deploy')
@authorize("system:huwang:deploy")
def deploy():
    res = db.session.query(Resources).filter(Resources.location == '外网边界').all()
    device = {}
    for rule in res:
        device[rule.hostname] = '%s(%s)' % (rule.hostname, rule.mgtip)
    return render_template('system/huwang/deploy.html', device=device)

3.3 日志处理代码

@bp.get('/deploy_log')
@authorize("system:huwang:temporary")
def deploy_log():
    query = db.session.query(Hwlog).filter(Hwlog.logger_name=='deploy_1policy').order_by(Hwlog.timestamp.desc()).layui_paginate()
    return table_api(
        data = [{
        'timestamp': record.timestamp,
        'logger_name': record.logger_name,
        'level': record.level,
        'message': record.message
        } for record in query.items], count = query.total)

3.4 一键部署后端执行代码

@bp.post('/exec_deploy')
@authorize("system:huwang:deploy")
def exec_deploy():
    hostname = request.form['firewall']
    policy_id = request.form['policyid']

    try:
        dev = db.session.query(Resources).filter(Resources.hostname==hostname).first()
        logger = setup_logger("deploy_policy")
        logger.info(f"开始部署防火墙策略,目标主机: {hostname}, 策略ID: {policy_id}")
        config = {
            "host": dev.mgtip,
            "vsys": dev.vsys,
            "username": dev.loginname,
            "password": dev.loginpass,
            "apikey": dev.apikey,
            "logger": logger
        }

        # 创建管理器实例
        if dev.loginmeth.lower() == 'api' and dev.vendor.lower() == 'fortigate':
            firewall = FortiGateManager(**config)
            result = firewall.deploy_block_policy(policy_id, "拦截策略")
            if result['success']:
                return success_api(str(result['message']))
            else:
                return fail_api(str(result['message']))

        else:
            return('不支持的产品和登陆方式')

    except Exception as e:
        print(f"部署拦截策略发生未知性错误: {str(e)}")

四、测试验证

4.1 主页面测试

4.2 策略冲突测试

4.3 防火墙本地日志验证

4.4 防护墙拦截策略部署成功

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容