用过阿里高防的都知道,高防有个很牛X的防CC功能配置:基于域名,基于某URL(精确匹配或后模糊匹配),限制某个时间跨度的请求频率,超过该频率会拉黑n分钟。废话少说,直接上图:
然而:
高防不是所有公司都用得起的(月费用1万以上),
高防配置的域名数量越来越苛刻(一级域名和二级域名数都有严格限制了),
高防也有抽风的时候,有很多时候发现该功能没起效果,
所以我们搞了个自己的防CC功能。
改方案暂取名lbwaf,主要功能包括手动拉黑(就是手动填IP黑名单),自动拉黑(重点功能,配置规则),自动拉黑支持白名单配置,支持查看规则触发的日志明细。
实时分析基于spark structure streaming,下一章介绍;本章介绍web功能和数据库设计。
1. WEB功能
贴2个主要页面
a)、黑名单列表
来源类型:api\spark\手动(目前未实现api)
spark对应具体的规则id;手动对应具体的用户名
b)、规则管理
规则包括:域名、URL、匹配类型(精确、后模糊)、时间范围、请求阈值、封禁时间
2. 数据库设计
主要表和JOB
存储过程:根据spark输出的数据,生成IP黑名单结果
CREATE PROCEDURE `proc_spark_ipblacklist`()
BEGIN
declare v_auto_ip_quota int default 1000; -- 支持最大自动拉黑IP数
declare v_id_last bigint; -- 上次处理到的id(含)
declare v_id_curr bigint; -- 当前id
declare v_ip_blacklist_cnt int; -- 现有的拉黑IP数
declare v_to_add bigint; -- 当前新增拉黑IP数
select id_deal_until into v_id_last from job_process where id=1;
select max(id) into v_id_curr from match_record;
select count(*) into v_ip_blacklist_cnt from ip_blacklist where source_type='spark';
start transaction;
-- 当前有新增IP
if (v_id_curr > v_id_last) then
-- 当前新增需要处理的IP数
select count(distinct rule_id,ip_addr) into v_to_add
from match_record t
where id > v_id_last
and id <= v_id_curr
and ip_addr not in (select ip_addr from ip_blacklist);
-- 新增数量大于配额,直接清空所有存量IP黑名单
if (v_to_add >= v_auto_ip_quota) then
delete from ip_blacklist where source_type='spark';
-- 新增数量与存量IP黑名单之和大于配额,删除存量IP黑名单中老的IP
elseif (v_to_add + v_ip_blacklist_cnt > v_auto_ip_quota) then
select v_to_add + v_ip_blacklist_cnt - v_auto_ip_quota into @v_to_delete;
prepare s1 from "delete from ip_blacklist where source_type='spark' order by create_time limit ?";
execute s1 using @v_to_delete;
end if;
-- 插入新增IP
insert into ip_blacklist(source,ip_addr,effective_time,status,source_type)
select distinct concat('rule',rule_id),ip_addr,
(select block_duration from rule where id=t.rule_id), 0,'spark'
from match_record t
where id > v_id_last
and id <= v_id_curr
and ip_addr not in (select ip_addr from ip_blacklist)
limit 1000;
update job_process set id_deal_until = v_id_curr where id = 1;
end if;
commit;
end;
存储过程:IP黑名单封禁到期后,修改状态,删除过期数据
CREATE PROCEDURE `proc_ip_blacklist_status_update`()
begin
update ip_blacklist
set status=1
where date_add(modify_time,INTERVAL effective_time minute) < now();
commit;
delete from ip_blacklist
where status = 1
and source_type='spark';
commit;
delete from ip_blacklist
where status = 1
and source_type='手动'
and modify_time < DATE_SUB(now(),INTERVAL 1 day);
commit;
end;
代码地址:https://github.com/meishd/waf_manager
web和数据库设计介绍完毕,下一章介绍spark实时分析日志的实现