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

部署运行你感兴趣的模型镜像

 目录

一、创建一键封禁菜单

二、前端页面设计

2.1 前端页面布局

2.2 前端代码

三、后端代码设计

3.1 一键封禁路由

3.2 一键封禁接口

3.3 一键封禁日志

四、IP地址合规检查

五、批量封禁测试

5.1 一次封禁200个IP地址测试

5.2 子网和IP范文封禁测试

5.3 动态地址组测试

5.4 IP地址格式检查测试

六、总结


     

通过前端页面输入多个IP地址列表,实现批量IP地址封禁操作。格式可以是单个IP地址,CIDR地址段和IP地址范围,例如:

        主机IP:112.111.1.1

        子网端:112.111.1.0/24

        范围:112.111.1.1-112.111.1.100

执行一键封禁时,将对输入的IP地址格式进行检查和格式化,不符合规范的IP地址将通过提示返回,前段修正输入的IP地址列表后重新提交。

一、创建一键封禁菜单

        通过PearAdmin的【系统管理】-【权限管理】在护网工具目录下创建【一键封禁】菜单,并设置权限标识和路径信息。

二、前端页面设计

2.1 前端页面布局

前端页面整体展现效果,上半部份为输入需要封建的IP地址列表,后半部分为封禁过程产生的日志信息。

2.2 前端代码

在PearAdmin项目的【templates】-【system】-【huwang】目录下新建文件block.html。

<!DOCTYPE html>
<html>
<head>
    <title>一键封禁</title>
    {% include 'system/common/header.html' %}
</head>
</head>
<body>
<div class="layui-fluid">
    <div class="layui-card">
        <fieldset class="layui-elem-field layui-field-title" style="margin-top: 10px;"><legend>IP地址封禁</legend></fieldset>
        <div class="layui-card-body">
            <form class="layui-form layui-form-pane" action="">
                <div class="layui-form-item layui-form-text">
                    <div class="layui-input-block">
                        <textarea name="iplist" required lay-verify="required" placeholder="示例:&#13;&#10;192.168.1.1&#13;&#10;192.168.10.0/24&#13;&#10;192.168.2.1-192.168.2.10&#13;&#10;" class="layui-textarea" style="height: 200px;"></textarea>
                    </div>
                </div>
                <br>
                <div class="layui-form-item layui-form-pane">
                    <div class="layui-input-block" style="margin-inline-start: 0%;">
                        <button class="layui-btn layui-btn-md" lay-submit lay-filter="block" >提交</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" style="margin-top: 10px;">
            <legend>封禁日志</legend>
        </fieldset>
        <div class="layui-card-body">
            <table id="log-table" lay-filter="log-table"></table>
        </div>
    </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(block)', function(data){//监听按钮
            $.ajax({
                url:"/system/huwang/exec_block",  //提交请求的URL
                data: JSON.stringify(data.field),
                dataType: 'json',
                contentType: 'application/json',
                type: 'post',
                success:function(result){
                    if (result.success){
                        layer.msg(result.msg, {icon: 1, time: 2000, title:'成功'}, function(){location.reload();});
                        return;
                    }else{
                        layer.msg(result.msg, { icon: 2, time: 4000, title:'失败' })
                    }
                },
                error:function(result){
                    alert("接口错误!!!"); //无返回或处理有报错时弹框
                }
            });
            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/block_log',
            page:{limit: 10,limits:[10,30,50]},
            cols: cols,
            skin: 'line',
            text: {none: '暂无设备信息'},
        })
    });
</script>
</html>

三、后端代码设计

3.1 一键封禁路由

在huwang.py文件中增加一键封禁页面路由。

@bp.get('/block')
@authorize("system:huwang:block")
def block():
    return render_template('system/huwang/block.html')

3.2 一键封禁接口

在huwang.py文件中增加一键封禁后端处理接口。

@bp.post('/exec_block')
@authorize("system:huwang:block")
def exec_block():
    req_json = request.get_json(force=True)
    iplist = str_escape(req_json.get('iplist'))

    ip_list = iplist.strip().split('\n')
    ip_list = ip_check(ip_list)

    if len(ip_list['error']) > 0:
        return fail_api('IP地址不正确:'+str(ip_list['error']))

    filter = []
    filter.append(Resources.location=='外网边界')
    filter.append(Resources.enable == 1)
    query = db.session.query(Resources).filter(*filter).all()
    logger = setup_logger("block_ip")
    for dev in query:
        try:
            logger.info(f"开始进行防火墙: {dev.hostname}封禁操作")
            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.block_ips(ip_list)
                if result['success']:
                    return success_api(str(result['message']))
                else:
                    return fail_api(str(result['message']))

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

        except Exception as e:
            print(f"封禁IP过程发生未知性错误: {str(e)}")

3.3 一键封禁日志

在huwang.py文件中增加一键封禁日志显示接口。

@bp.get('/block_log')
@authorize("system:huwang:temporary")
def block_log():
    query = db.session.query(Hwlog).filter(Hwlog.logger_name=='block_ip').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)

四、IP地址合规检查

        在PearAdmin项目【applications】-【common】-【utils】目录下新建check_ip.py实现IP地址格式检查功能。

import re
from IPy import IP
def ip_check(ip_list):
    # 定义正则表达式模式
    single_ip_pattern = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
    cidr_pattern = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/([0-2]?[0-9]|3[0-2])$'
    ip_range_pattern = r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)-((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'

    # 依次检查是否匹配三种格式
    result = {'ok':[], 'error':[]}
    for item in ip_list:
        if re.match(single_ip_pattern, item):
            tmp = {'name':item+'/32','type':'ipmask','subnet':item + ' 255.255.255.255'}
            if tmp not in result['ok']:
                result['ok'].append(tmp)
        elif re.match(cidr_pattern, item):
            try:
                ip = IP(item)
                ip_cidr = f"{ip.strNormal(0)} {ip.netmask().strNormal(0)}"
                tmp = {'name':item,'type':'ipmask','subnet':ip_cidr}
                if tmp not in result['ok']:
                    result['ok'].append(tmp)
            except:
                result['error'].append(item)
        elif re.match(ip_range_pattern, item):
            ip_start = item.split('-')[0]
            ip_end = item.split('-')[1]
            if ip_start > ip_end:
                result['error'].append(item)
            else:
                tmp = {'name': item, 'type': 'iprange', 'start-ip': item.split('-')[0], 'end-ip': item.split('-')[1]}
                if tmp not in result['ok']:
                    result['ok'].append(tmp)
        else:
            result['error'].append(item)
    return (result)

五、批量封禁测试

5.1 一次封禁200个IP地址测试

5.2 子网和IP范文封禁测试

日志记录

5.3 动态地址组测试

5.4 IP地址格式检查测试

六、总结

        当封禁超过200个地址时,后台处理过程需要时间,前段页面会有少许等待。后续考虑有没有办法优化,从而提高封禁执行效率。        

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

候鸟-南飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值