JAVA实现动态IP黑名单过滤

 一些恶意用户(可能是黑客、爬虫、DDoS 攻击者)可能频繁请求服务器资源,导致资源占用过高。因此需要一定的手段实时阻止可疑或恶意的用户,减少攻击风险。

通过 IP 封禁,可以有效拉黑攻击者,防止资源被滥用,保障合法用户的正常访问。对于我们的需求,不让拉进黑名单的IP 访问任何接口

Sentinel本身支持请求来源的黑白名单判断,但默认是对应用级别进行判断,需要改造来源的获取方式为获取请求客户端的 IP,可参考这篇文章自定义来源。但是需要一定成本的

需求分析

使用Nacos是更轻量的动态 IP 黑白名单过滤的常用设计和实现方法。主要考虑以下几点:

IP 黑名单存储在哪里?

一般 IP 黑名单是动态增加的、需要持久化保存。常见的持久化方式包括数据库、配置文件或分布式存储系统(如 Redis),可以根据需要选择。

如何便捷地动态修改 IP 黑名单?

为了方便动态修改 IP 黑名单,所以这里考虑将 配置统一放入 配置中心,通过配置中心的管理页面,开发人员可以便捷地动态修改黑名单规则。Java 项目中,常用的配置中心是 Nacos。

黑白名单的判断逻辑应在哪里处理?

黑白名单逻辑通常部署在高性能的网关或 CDN 上,能更早地拦截非法请求,减轻后端压力。小型项目中,也可直接在应用程序的过滤器中处理

使用何种数据结构保存黑名单? 如何快速匹配用户请求的 IP 是否在黑名单中?

为了高效判断每个用户请求的 IP 是否在黑名单中,首先建议将IP 黑名单从持久化存储同步到本地缓存中,避免频繁查询远程数据源。

对于大流量刷题网站,大规模黑名单使用 布隆过滤器 来存储和过滤黑名单是比较好的,可以节约内存空间、提高检测效率。

最终方案如下

  1. 使用Nacos配置中心存储和管理 IP 黑名单

  2. 后端服务利用Web过滤器判断每个用户请求的 IP

  3. 后端服务利用布隆过滤器过滤 IP 黑名单

布隆过滤器

布隆过滤器是一种高效的概率数据结构,常用于检测一个元素是否在一个集合中,可以有效减少数据库的查询次数,解决缓存穿透等问题

布隆过滤器是由一个位数组k个独立的哈希函数组成。

  • 添加元素时,通过k个哈希函数将元素映射到位数组的k个位置上,将这些位置设置为 1。

  • 查询元素是否存在时,同样计算k个位置

    • 如果所有位置都是1,则说明元素可能存在(因为可能多个不同值通过哈希函数映射到同一位

    • 只要有一个位置为 0,就可以确定元素一定不存在。

其次布隆过滤器不能删除元素,因为可能多个元素映射到同一个位置,修改了这个位置,就会导致其它元素判断错误

Bloom Filter 的误判率与以下因素有关

  • 位数组的大小: 位数组越大,误判率越低,但空间开销会增大。(值会更离散)

  • 哈希函数的个数: 哈希函数越多,误判率越低,但计算成本会增加。(Hash 一次冲突,那我就多 Hash 几次,减少冲突概率)

  • 元素数量: 存入的元素越多,误判率会增加。

布隆过滤器适用场景

布隆过滤器一般都在海量数据判断场景,且可以允许误判。

  1. redis结合bitmap使用,解决缓存穿透的问题

  2. 黑名单校验,识别垃圾邮件

比如: 识别垃圾邮件,把所有黑名单地址都放在布隆过滤器中,在收到邮件时,判断邮件地址是否在布隆过滤器中即可。

Nacos配置中心

官网:Nacos官网| Nacos 配置中心 | Nacos 下载| Nacos 官方社区 | Nacos 官网 一个更易于构建云原生应用的动态服务发现,并且自动配置持久化,配置管理和服务管理平台

Nacos=Eureka+Config+Bus  比 SpringCloud Consul更为强大,并且自带负载均衡功能

下载安装运行

Nacos 快速开始 | Nacos 官网

https://github.com/alibaba/nacos/releases

解压直接运行bin目录下输入cmd命令
startup.cmd -m standalone      #代表单机非集群模式运行

运行成功后直接访问 http://localhost:8848/nacos/index.html

默认账号密码都是 nacos

后端开发

运行Nacos,创建配置,表示黑名单

blackIpList:- "1.1.1.1"- "2.2.2.2"

项目引入依赖

Nacos 融合 Spring Boot,成为注册配置中心 | Nacos 官网

<!--版本 0.2.x.RELEASE 对应的是 Spring Boot 2.x版本-->
<dependency><groupId>com.alibaba.boot</groupId><artifactId>nacos-config-spring-boot-starter</artifactId><version>0.2.12</version>
</dependency>
# 配置中心
nacos:config:server-addr: 127.0.0.1:8848  # nacos 地址bootstrap:enable: true         # 预加载data-id: praxisAI    # 控制台填写的 Data IDgroup: DEFAULT_GROUP  # 控制台填写的 grouptype: yaml            # 选择的文件格式auto-refresh: true    # 开启自动刷新
创建黑名单过滤工具类

新建blackfilter包,黑名单过滤相关的代码都放到该包下,模块化。参考文章,如果是分布式,还可以考虑 Redisson。可以用 Hutool 或 Guava 库自带的 bloomfilter,此处由于项目已经使用了 Hutool 工具库,就用其自带的BitMapBloomFilter即可。

/*** 黑名单过滤工具类*/
@Slf4j
public class BlackIpUtils {//静态的布隆过滤器,存IP黑名单,默认大小1000private static BitMapBloomFilter bloomFilter;
​// 判断 ip 是否在黑名单里public static boolean isBlackIp(String ip) {//true 表示可能在黑名单里//false 一定不在黑名单里return bloomFilter.contains(ip);}
​//获取 nacos 上的黑名单,添加到布隆过滤器中public static void rebuildBlackIp(String configInfo) {//判断配置信息是否为空if (StrUtil.isBlank(configInfo)) {configInfo = "{}";}// 解析 yaml 文件Yaml yaml = new Yaml();//将传入的配置信息解析成 Map 对象Map map = yaml.loadAs(configInfo, Map.class);
​// 获取配置中的 IP 黑名单List<String> blackIpList = (List<String>) map.get("blackIpList");
​// 加锁防止多线程修改布隆过滤器synchronized (BlackIpUtils.class) {//黑名单不为空if (CollUtil.isNotEmpty(blackIpList)) {// 注意构造参数的设置,容量越大,误判率越低BitMapBloomFilter bitMapBloomFilter = new BitMapBloomFilter(1000);//遍历黑名单,将黑名单添加到布隆过滤器中for (String blackIp : blackIpList) {bitMapBloomFilter.add(blackIp);}bloomFilter = bitMapBloomFilter;}//黑名单为空else {bloomFilter = new BitMapBloomFilter(1000);}}}
}

创建Nacos配置监听类

@RefreshScope配置动态刷新,当Nacos配置变化时,可以触发工具类的重新初始化,更新黑名单,但是仅仅只是更新到一个列表里,布隆过滤器内部是由代码控制的

所以这里直接通过 Nacos 控制台获取示例代码,在blackfilter包中新增监听器代码

整体流程

  1. Spring 容器启动后,调用 afterPropertiesSet 方法。

  2. 从 Nacos 获取当前的黑名单配置,并将其加载到布隆过滤器中。

  3. 并且注册一个监听器,用于监听 Nacos 配置的变化。

  4. 处理配置变化

    • 当 Nacos 配置发生变化时,监听器的 receiveConfigInfo 方法会被触发。

    • 新的配置内容会被传递给 BlackIpUtils.rebuildBlackIp 方法,重新构建布隆过滤器。

  5. 使用自定义线程池异步处理nacos配置变化,避免阻塞主线程。

/*** Nacos 监听器*/
@Slf4j
@Component
//表示该类会在 Spring 容器初始化完成后自动调用 afterPropertiesSet 方法
public class NacosListener implements InitializingBean {@NacosInjectedprivate ConfigService configService;  //与 nacos 配置中心交互@Value("${nacos.config.data-id}")private String dataId;@Value("${nacos.config.group}")private String group;@Overridepublic void afterPropertiesSet() throws Exception {log.info("nacos 监听器启动");//从 Nacos 获取指定 dataId 和 group 的配置内容String config = configService.getConfigAndSignListener(dataId, group, 3000L,new Listener() { //注册一个nacos监听器,监听配置信息的变化//定义线程工程final ThreadFactory threadFactory = new ThreadFactory() {//原子类,用于生成线程名称private final AtomicInteger poolNumber = new AtomicInteger(1);@Overridepublic Thread newThread(@NotNull Runnable r) {Thread thread = new Thread(r);thread.setName("refresh-ThreadPool" + poolNumber.getAndIncrement());return thread;}};//自定义线程池:使用固定大小的线程池,传入线程工厂,用于异步处理配置变化的逻辑final ExecutorService executorService = Executors.newFixedThreadPool(1, threadFactory);// 通过线程池异步处理黑名单变化的逻辑@Overridepublic Executor getExecutor() {return executorService;}// 监听后续黑名单变化//当nacos配置中心配置信息发生变化时,会接收新的配置configInfo加载到布隆过滤器中@Overridepublic void receiveConfigInfo(String configInfo) {log.info("监听到配置信息变化:{}", configInfo);//将新的黑名单配置加载到布隆过滤器中BlackIpUtils.rebuildBlackIp(configInfo);}});// 初始化黑名单BlackIpUtils.rebuildBlackIp(config);}
}
创建黑名单过滤器

黑名单应该对所有请求生效( 不止是 Controler 的接口 ),所以基于WebFilter实现而不是 AOP 切面。WebFilter的优先级高于@Aspect切面,因为它在整个 Web 请求生命周期中更早进行处理。

请求进入时的顺序:

  1. 首先,WebFilter拦截 HTTP 请求,并可以根据逻辑决定是否继续执行请求。

  2. 如果请求到过滤器并进入 Spring 的 Bean( 例如 Controller层 ),此时AOP切面生效,对匹配的 Bean 方法进行拦截

  3. 如果 @Aspect 没有阻止执行,最终请求到达 @Controller 或 @RestController 的方法

/*** 全局 IP 黑名单过滤请求拦截器*/
//声明一个过滤器,拦截所有的 HTTP 请求
@WebFilter(urlPatterns = "/*", filterName = "blackIpFilter")
public class BlackIpFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//获取客户端IP地址String ipAddress = NetUtils.getIpAddress((HttpServletRequest) servletRequest);//判断IP地址是否在黑名单中(布隆过滤器中)if (BlackIpUtils.isBlackIp(ipAddress)) {//如果在,则返回错误信息servletResponse.setContentType("text/json;charset=UTF-8");servletResponse.getWriter().write("{\"errorCode\":\"-1\",\"errorMsg\":\"黑名单IP,禁止访问\"}");return;}//放行请求filterChain.doFilter(servletRequest, servletResponse);}
}

最后需要在需要在启动类上加上@ServletComponentScan,这样过滤器才会被扫描到。

@SpringBootApplication
@MapperScan("com.zr.praxisai.mapper")
@EnableScheduling
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)  //开启SpringAOP功能
@ServletComponentScan  //扫描原生的 Servlet 组件(如过滤器、监听器、Servlet)
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}
}
测试

通过 Nacos 控制台修改配置,本地测试的话直接加入本机 IP 即可,Nacos控制台可以看到改动记录和历史版本

blackIpList:- "1.1.1.1"- "2.2.2.2"- "0:0:0:0:0:0:0:1"

通过修改Nacos配置查看后端监听情况

通过Swagger测试发现直接打不开了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/42582.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RocketMQ可视化工具使用 - Dashboard(保姆级教程)

1、github拉取代码&#xff0c;地址&#xff1a; https://github.com/apache/rocketmq-dashboard 2、指定Program arguments&#xff0c;本地启动工程 勾上这个Program arguments&#xff0c;会出现多一个对应的框 写入参数 --server.port1280 --rocketmq.config.namesrvAddr…

湖南(源点咨询)市场调研 商业综合体定位调研分享(上篇)

​ 该项目位于某新一线城市的城市副中心区域&#xff0c;系一个正在发展中的中央居住区&#xff0c;项目本身是一个涵盖社区综合服务中心、商业、文体活动中心、卫生服务、社区养老等多功能复合的公共配套项目&#xff0c;本次调研主要针对其商业&#xff08;及其他可商用的&a…

硬件测试工装设计不合理的补救措施

硬件测试工装设计不合理的补救措施主要包括重新评估设计需求、优化工装结构、强化工装校准与验证。其中&#xff0c;优化工装结构尤其重要&#xff0c;通过结构优化能够有效解决因设计不合理导致的测试准确性下降和可靠性不足的问题。根据工程实践数据&#xff0c;经过优化结构…

PyQt6实例_批量下载pdf工具_使用pyinstaller与installForge打包成exe文件

目录 前置&#xff1a; 步骤&#xff1a; step one 准备好已开发完毕的项目代码 step two 安装pyinstaller step three 执行pyinstaller pdfdownload.py&#xff0c;获取初始.spec文件 step four 修改.spec文件&#xff0c;将data文件夹加入到打包程序中 step five 增加…

open-cv的安装

python -m pip install numpy matplotlib opencv-python 【记得科学上网&#xff0c;不然太慢了】

AI写一个视频转图片帧工具(python)

现在的AI写python太方便了 说的话 我想用python实现一个能够将视频的所有帧数转化为图片的软件&#xff0c;可以自由配置转换的帧率或者全部&#xff0c;需要有界面&#xff0c;我需要增加一点功能&#xff0c;就是我需要读取出视频的分辨率&#xff0c;然后设置输出帧的分辨…

Axure RP9.0教程: 多级联动【设置选项改变时->情形->面板状态】(给动态面板元件设置相关交互事件的情形,来控制其他面板不同的状态。)

文章目录 引言I 多级联动(省、市、区)实现思路添加三省、市、区下拉列表给省下拉框添加数据源将市、区下拉框添加不同状态,分别以省、市命名给省下拉控件设置选项改变时的交互事件省下拉控件的交互事件情形市下拉交互事件的配置II 知识扩展: 展示省 → 地级市 → 区县的多级…

浙江大学|DeepSeek系列专题公开课|第一季|PDF+视频(全)

大家好&#xff0c;我是吾鳴。 之前吾鳴给大家分享过由浙大出品的DeepSeek系列专题公开课的教程&#xff0c;不过都比较零散&#xff0c;而且都只有PDF&#xff0c;有粉丝朋友直呼看得不过瘾。今天吾鳴把视频也给大家找来了&#xff0c;而且把第一季的DeepSeek系列公开课也稍做…

数据可视化(matplotlib)-------图表样式美化

目录 一、图表样式概述 &#xff08;一&#xff09;、默认图表样式 &#xff08;二&#xff09;、图表样式修改 1、局部修改 2、全局修改 二、使用颜色 &#xff08;一&#xff09;、使用基础颜色 1、单词缩写或单词表示的颜色 2、十六进制/HTML模式表示的颜色 3、RGB…

SpringBoot3解决跨域请求问题(同源策略、JSONP、CORS策略)(Access-Control-Allow-Origin)(2025详细教程)

目录 浏览器跨域请求问题。 浏览器同源策略。 第三方API调用。 前后端分离项目。 一、JSONP。&#xff08;dataType:jsonp&#xff09; &#xff08;1&#xff09;代码示例。 <1>前端ajax04.jsp页面。(发起Ajax请求) <2>后端springboot接口。(/hello)(返回JSONPObj…

rent8_wechat-新增提醒收租功能

本次更新中&#xff0c;rent8_wechat 小程序全新推出了“提醒收租”功能&#xff0c;为房东提供更加便捷的收租体验。房东只需在小程序内点击“提醒收租”按钮&#xff0c;系统便会在需要收租当天的上午9点准时推送通知&#xff0c;贴心提醒房东及时收取租金。 以下是该功能的…

诠视科技MR眼镜如何安装apk应用

诠视科技MR眼镜如何安装apk应用 1、使用adb工具安装1.1 adb工具下载1.2 解压adb文件1.3 使用adb安装apk 2、拷贝到文件夹安装 1、使用adb工具安装 1.1 adb工具下载 点击下面的链接开始下载adb工具&#xff0c;下载结束以后解压文件。 下载链接: https://download.xvisiotech…

JAVA学习*异常

什么是异常 在 Java 里&#xff0c;异常是指程序运行期间出现的不正常状况&#xff0c;它会中断程序的正常执行流程。 异常的分类 Java 中的异常是对象&#xff0c;这些对象都继承自 Throwable类。Throwable类有两个主要的子类&#xff1a;Error 和 Exception。 Error类表示…

DataGear 5.3.0 制作支持导出表格数据的数据可视化看板

DataGear 内置表格图表底层采用的是DataTable表格组件&#xff0c;默认并未引入导出数据的JS支持库&#xff0c;如果有导出表格数据需求&#xff0c;则可以在看板中引入导出相关JS支持库&#xff0c;制作具有导出CSV、Excel、PDF功能的表格数据看板。 在新发布的5.3.0版本中&a…

【电气设计】接地/浮地设计

在工作的过程中&#xff0c;遇到了需要测量接地阻抗的情况&#xff0c;组内讨论提到了保护接地和功能接地的相关需求。此文章用来记录这个过程的学习和感悟。 人体触电的原理&#xff1a; 可以看到我们形成了电流回路&#xff0c;导致触电。因此我们需要针对设备做一些保护设计…

【计算机操作系统】线程的概念和特点

1、什么是线程&#xff0c;为什么要引入线程&#xff1f; 还没引入进程之前&#xff0c;系统中各个程序只能串行执行。 比如&#xff1a;当我们在使用QQ与好友视频时&#xff0c;我们可以给其他好友发信息&#xff0c;发送文件...&#xff0c;我们知道进程是程序的一次执行&am…

【C++数据库】SQLite3数据库连接与操作

注意:本文代码均为C++20标准下实现 一、SQLite3库安装 1.1 安装库文件 【工具】跨平台C++包管理利器vcpkg完全指南 vcpkg install sqlite3# 集成至系统目录,之前执行过此命令的无需再次执行 vcpkg integrate install1.2 验证代码 在VS2022中新建控制台项目,测试代码如下…

CLion下载安装(Windows11)

目录 CLion工具下载安装其他 CLion CLion-2024.1.4.exe 工具 系统&#xff1a;Windows 11 下载 1.通过百度网盘分享的文件&#xff1a;CLion-2024.1.4.exe 链接&#xff1a;https://pan.baidu.com/s/1-zH0rZPCZtQ60IqdHA7Cew?pwdux5a 提取码&#xff1a;ux5a 安装 打开…

‘无法定位程序输入点kernel32.dll’详细的修复方法,一键快速修复kernel32.dll

在 Windows 系统运行过程中&#xff0c;若程序提示“无法定位程序输入点 kernel32.dll”&#xff0c;往往意味着程序调用了 kernel32.dll 中不存在或已变更的函数接口。作为系统的核心动态链接库&#xff0c;kernel32.dll 承担着内存管理、进程控制、文件操作等底层功能&#x…

二层综合实验

拓扑图 实验要求 1.内网IP地址使用172.16.6.0/16分配 2.sw1和sW2之间互为备份 3.VRRP/STP/VLAN/Eth-trunk均使用 4.所有Pc均通过DHCP获取IP地址 5.ISP只能配置IP地址 6.所有电脑可以正常访问IsP路由器环回 实验思路 这是一个二层综合实验每当拿到一个实验看清楚要求之后都有…