目录
一、创建一键解禁菜单
二、前端页面设计
2.1 前端页面展现
2.2 前端代码设计
三、后端代码设计
3.1 一键解禁路由
3.2 一键解禁接口
3.3 一键解禁日志
3.4 IP地址合规检查
四、测试验证
4.1 解禁不存在的IP地址
4.2 解禁单个IP地址
4.3 解禁IP地址范围
4.4 防火墙本地日志记录
在安全运营的实际场景中,IP 地址的封禁操作虽为保障网络边界安全的重要手段,但误封情况却难以完全规避。这种误封可能源于威胁情报的偏差、自动化规则的过度触发,或是人工研判的疏漏 —— 例如将正常用户的动态 IP 误判为攻击源,或将内部办公 IP 纳入了封禁范围。一旦发生误封,不仅会影响合法业务的正常访问,导致用户投诉、业务中断等问题,严重时还可能造成直接的经济损失或声誉损害。因此,建立一套高效、精准的 IP 解封机制,与封禁操作形成闭环,是安全运营体系中不可或缺的关键环节。
一、创建一键解禁菜单
通过PearAdmin的【系统管理】-【权限管理】在护网工具目录下创建【一键解禁】菜单,并设置权限标识和路径信息。

刷新页面左侧导航即可显示解禁菜单

二、前端页面设计
2.1 前端页面展现
一键解禁主页面与一键封禁主界面相同设计,只是访问后端不同接口实现不同功能而已。

2.2 前端代码设计
在PearAdmin项目的【templates】-【system】-【huwang】目录下新建文件unblock.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"><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="示例:
192.168.1.1
192.168.10.0/24
192.168.2.1-192.168.2.10
" class="layui-textarea"></textarea>
</div>
</div>
<br>
<div class="layui-form-item layui-form-pane">
<div class="layui-input-block">
<button class="layui-btn layui-btn-md" lay-submit lay-filter="unblock" >提交</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>
</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(unblock)', function(data){//监听按钮
$.ajax({
url:"/system/huwang/exec_unblock", //提交请求的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/unblock_log',
page:{limit: 10,limits:[10,30,50]},
cols: cols,
skin: 'line',
text: {none: '暂无设备信息'},
})
});
</script>
</html>
三、后端代码设计
3.1 一键解禁路由
@bp.get('/unblock')
@authorize("system:huwang:unblock")
def unblock():
return render_template('system/huwang/unblock.html')
3.2 一键解禁接口
@bp.post('/exec_unblock')
@authorize("system:huwang:unblock")
def exec_unblock():
req_json = request.get_json(force=True)
iplist = str_escape(req_json.get('iplist'))
ip_list = iplist.strip().split('
')
ip_list = ip_check(ip_list)
if len(ip_list['error']) > 0:
return fail_api('IP地址不正确:'+str(result['error']))
filter = []
filter.append(Resources.location == '外网边界')
filter.append(Resources.enable == 1)
query = db.session.query(Resources).filter(*filter).all()
logger = setup_logger("unblock_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
}
print(config)
# 创建管理器实例
if dev.loginmeth.lower() == 'api' and dev.vendor.lower() == 'fortigate':
firewall = FortiGateManager(**config)
result = firewall.unblock_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 一键解禁日志
@bp.get('/unblock_log')
@authorize("system:huwang:temporary")
def unblock_log():
query = db.session.query(Hwlog).filter(Hwlog.logger_name=='unblock1_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)
3.4 IP地址合规检查
此处与一键封禁代码相同,请参考《PearAdmin二次开发之防火墙封禁工具-一键封禁篇》
四、测试验证
4.1 解禁不存在的IP地址

4.2 解禁单个IP地址

4.3 解禁IP地址范围

4.4 防火墙本地日志记录

© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END


















暂无评论内容