NetCore项目实现IP黑名单功能

文章目录

前言

使用场景:使用IP黑名单防止已知恶意 IP 地址的访问,降低系统被攻击的风险。阻止来自特定 IP 地址的大量请求,可以减轻分布式拒绝服务(DDoS)攻击的影响。通过监控访问日志,可以发现异常访问行为,并将可疑 IP 地址加入黑名单进而拒绝特别IP访问网站。

使用技术:Net8.0,Redis缓存(用来存储黑名单IP)

代码配置

首先创建中间件页面

csharp 复制代码
 public class IpBlacklistMiddleware
 {
     private readonly RequestDelegate next;
     private IIpBlacklistService _blacklistManager;

     public IpBlacklistMiddleware(RequestDelegate next, IIpBlacklistService blacklistManager)
     {
         this.next = next;
         _blacklistManager = blacklistManager;
     }

     public async Task InvokeAsync(HttpContext context)
     {
         //获取到用户真实IP地址
         var remoteIp = context.GetUserIp()?.Replace("::ffff:", "");

         // 检查 IP 是否在黑名单中
         if (!string.IsNullOrEmpty(remoteIp) && _blacklistManager.IsIpBlacklisted(remoteIp))
         {
             // 返回 403 Forbidden 状态码
             context.Response.StatusCode = StatusCodes.Status403Forbidden;
             await context.Response.WriteAsync("您的IP被列入黑名单");
             return;
         }
         await next(context);
     }
 }

中间件属于全局规则 ,比如请求控制器接口、服务器图片路径、css文件、js文件等等,即使静态文件请求也会进行拦截处理 。而Ip中间件的作用就是:当用户访问网站的时候,请求到达服务器后会先进入Ip中间件进行校验当前用户网络IP是否存储在Redis黑名单里面,如果是黑名单IP,直接驳回网络请求,不允许当前用户访问网站并返回403状态码

中间件可以在应用程序的整个生命周期中应用于所有请求,而无需在每个控制器中重复定义,所以只需要定义一遍就可以了。

其次注册服务和中间件
在 Program.cs 中注册 Redis 服务和中间件:

csharp 复制代码
var builder = WebApplication.CreateBuilder(args);

//reids配置
builder.Services.AddSingleton(new RedisService(builder.Configuration["Redis:ConnectionString"]));

builder.Services.AddControllers();

var app = builder.Build();

// Ip中间件
app.UseMiddleware<IpBlacklistMiddleware>();

app.UseAuthorization();

app.MapControllers();

app.Run();

这时候在网站运行的时候,就已经开启了中间件全局拦截。

然后再填写Redis的配置

在appsettings.json里面填写redis的连接配置:

csharp 复制代码
 "RedisConn": "127.0.0.1,Password=111111,SyncTimeout=15000", //redis连接字符串

在redis公共方法里面进行配置:

csharp 复制代码
 public RedisCacheService()
  {
      var csredis = new CSRedisClient(AppSetting.RedisConnectionString);
      RedisHelper.Initialization(csredis);
  }
csharp 复制代码
 public class IpBlacklistService : IIpBlacklistService
 {
     private RedisCacheService _redisCacheService;
     private const string BlacklistKey = "ip_blacklist";

     public IpBlacklistService(RedisCacheService redisCacheService)
     {
         _redisCacheService = redisCacheService;
     }

     //添加 IP 到黑名单
     public bool AddIp(string ip)
     {
         if (!string.IsNullOrWhiteSpace(ip))
         {
             _redisCacheService.SAddToSet(BlacklistKey, ip);
             return true;
         }
         return false;
     }
     //检查 IP 是否在黑名单中
     public bool IsIpBlacklisted(string ip)
     {
         if (string.IsNullOrWhiteSpace(ip))
         {
             return false;
         }
         // 使用 RedisCacheService 检查 IP 是否在黑名单中
         return _redisCacheService.Exists(BlacklistKey) &&
                _redisCacheService.IsMember(BlacklistKey, ip);
     }

     //从黑名单中移除 IP
     public bool RemoveIp(string ip)
     {
         if (!string.IsNullOrWhiteSpace(ip))
         {
             _redisCacheService.RemoveFromSet(BlacklistKey, ip);
             return true;
         }
         return false;
     }
 }

然后在控制器中编写Api

csharp 复制代码
[JWTAuthorize]
[Route("/api/IpBlack")]
public class IpBlackController : Controller
{
    private readonly IIpBlacklistService _ipBlacklistService;
    public IpBlackController(IIpBlacklistService ipBlacklistService)
    {
        _ipBlacklistService = ipBlacklistService;
    }
    // 添加 IP 到黑名单
    [HttpPost, Route("Add"), AllowAnonymous]
    public ActionResult AddIp(string ip)
    {
        if (string.IsNullOrWhiteSpace(ip))
        {
            return Json(false);
        }
        try
        {
            var result = _ipBlacklistService.AddIp(ip);
            return Json(new { code = 200, status=result });
        }
        catch (Exception ex)
        {
            return Json(new { code = 400, status = false });
        }
    }
    [HttpPost("Remove")]
    //[ApiActionPermission(ActionRolePermission.SuperAdmin)]
    [AllowAnonymous]
    public ActionResult RemoveIp([FromBody] string ip)
    {
        if (string.IsNullOrWhiteSpace(ip))
        {
            return Json(false);
        }
        var result = _ipBlacklistService.RemoveIp(ip);
        return Json(result);
    }

注意:项目使用了Jwttoken进行身份验证,但是ip黑名单的接口不需要身份验证,所以在接口头部增加AllowAnonymous取消身份验证。

到此代码开发部分算是完成。

下面可以增加一些测试:使用Postman增加黑名单Ip

然后在redis里面就可以看到已经存在当前Ip值。

最后使用Jmeter测试工具进行对接口添加到Redis的数据性能测试。

并发生成5000条数据,没有问题,校验redis并发添加问题。

技术细节

在本地开发阶段,为了顺利进行项目开发,以下工具和配置是必需的:

1.Redis 客户端:

在本地电脑上安装 Redis 客户端,例如 RedisDesktopManager。这样可以方便地管理和查看 Redis 数据库中的数据。

注意:如果项目中配置的 Redis 地址指向本地,但本地未安装 Redis,将会导致连接错误。
2.性能测试:

使用 JMeter 软件进行性能测试,可以模拟大量用户请求,以评估系统的响应能力和稳定性。
3.接口测试:

使用 Postman 进行接口测试,方便地发送请求并查看返回结果,确保 API 的正确性和性能。
4.IP 校验:

在校验用户 IP 时,需要注意获取到的 IP 地址可能是 IPv6 格式。在这种情况下,需要去除前缀 ::ffff:,以便进行准确的校验。

小结

代码不算多,也容易理解,主要是各种工具的配合使用需要慢慢去配置,这个需要花费一些时间来熟悉。

相关推荐
云罗张晓_za89866827 分钟前
抖音“碰一碰”发视频:短视频社交的新玩法
android·c语言·网络·线性代数·矩阵·php
世界级小趴菜30 分钟前
综合实验练习实验报告
网络
ZTLJQ2 小时前
黑客实战教程-SQL注入攻击与跨站脚本(XSS)攻击
网络·安全·网络安全·网络攻击模型
黑客Ash3 小时前
b s架构 网络安全 网络安全架构分析
网络·web安全·架构
m0_748245744 小时前
C#数据库操作系列---SqlSugar完结篇
网络·数据库·c#
一ge科研小菜鸡5 小时前
DeepSeek 与网络安全:AI 驱动的智能防御
网络
✿ ༺ ོIT技术༻5 小时前
Linux:网络编程套接字及UDP
linux·网络·udp
写代码写到手抽筋6 小时前
结合实际讲NR系列2—— SIB1
网络·5g
doubt。6 小时前
3.攻防世界 unseping(反序列化与魔术方法)
网络·web安全·网络安全·php·代码复审
聪聪06066 小时前
ESP8266配置为TCP客户端,连接电脑和手机(使用Arduino配置)
服务器·网络·tcp/ip