网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
csharp
csharp
csharp
csharp
csharp
csharp
csharp
readme

基于行为的IP限流服务使用指南

🎯 概述

这是一个基于行为的分布式IP限流服务,专注于限制可疑行为而非正常请求频率。适用于多服务器部署和负载均衡环境。核心理念:

  1. 正常访问不限速 - 允许用户高频率正常访问
  2. 可疑行为记录 - 只有被安全规则拦截时才计数
  3. 行为阈值限流 - 超过可疑行为阈值则限流封禁
  4. 渐进式延迟 - 被限流的IP会有延迟惩罚,增加攻击成本
  5. 分布式共享 - 多个服务器实例共享限流状态

核心特性

  • 🎯 行为导向 - 基于可疑行为而非请求频率限流
  • 🌐 多服务器支持 - 适用于负载均衡、微服务环境
  • 🚀 FusionCache 集成 - 本地缓存 + Redis 分布式缓存
  • UTC 时间统一 - 避免时区问题,确保跨服务器一致性
  • 🔄 异步架构 - 所有缓存操作异步化,提升性能
  • 🛡️ 安全延迟 - 对被限流的IP实施延迟惩罚
  • 🗑️ 自动清理 - 依赖 FusionCache 自动过期机制

🚀 快速开始

1. 注册服务

// Program.cs 或 Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    // 首先确保已注册 FusionCache (通常在主项目中已配置)
    services.AddFusionCache()
        .WithDistributedCache(...)
        .WithBackplane(...);
    
    // 注册限流服务
    services.AddScoped<IIpRateLimitService, IpRateLimitService>();
    
    // 配置限流参数
    services.Configure<RateLimitConfig>(config =>
    {
        config.WindowSizeMinutes = 5;
        config.MaxBlocksPerWindow = 3;
        config.BlockDurationMinutes = 30;
        config.BlockedDelayBaseMs = 2000;
        config.BlockedDelayMaxMs = 10000;
    });
}

2. 配置中间件

public void Configure(IApplicationBuilder app)
{
    // 添加限流中间件(必须在 RejectBots 之前)
    app.UseMiddleware<RateLimitMiddleware>();
    
    // 添加安全检查中间件
    app.UseMiddleware<RejectBots>();
    
    // 其他中间件
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints => { ... });
}

3. 配置文件示例

appsettings.json

{
  "RateLimit": {
    "WindowSizeMinutes": 5,
    "MaxBlocksPerWindow": 3,
    "BlockDurationMinutes": 30,
    "CleanupIntervalMinutes": 60,
    "BlockedDelayBaseMs": 2000,
    "BlockedDelayMaxMs": 10000
  }
}

🔧 配置参数详解

参数默认值说明建议值
WindowSizeMinutes5统计时间窗口(分钟)5-15分钟
MaxBlocksPerWindow3窗口内最大拦截次数3-5次
BlockDurationMinutes30封禁持续时间(分钟)15-60分钟
CleanupIntervalMinutes60清理间隔(分钟)30-120分钟
BlockedDelayBaseMs2000被限流时的基础延迟(毫秒)1000-3000ms
BlockedDelayMaxMs10000被限流时的最大延迟(毫秒)5000-30000ms

💡 行为限流策略说明

1. 核心理念

正常请求: 无限制,立即处理
可疑行为: 被 RejectBots 拦截时计数
达到阈值: 限流封禁,延迟处理所有请求

2. 限流触发条件

时间窗口: 5分钟内
拦截次数: 被安全规则拦截 3 次
限流时长: 30分钟
延迟处理: 2秒-10秒渐进式延迟

3. 延迟计算示例

配置: BlockedDelayBaseMs=2000, BlockedDelayMaxMs=10000

拦截次数 | 延迟时间
1-3     | 2000ms (基础延迟)
4-6     | 4000ms 
7-9     | 6000ms
10+     | 10000ms (最大延迟)

4. 与传统限流的区别

传统限流: 限制所有请求频率
行为限流: 只限制可疑行为

例如:
- 正常用户快速浏览: ✅ 允许
- 正常API高频调用: ✅ 允许  
- 访问非法路径: ❌ 计数
- 恶意爬虫行为: ❌ 计数
- SQL注入尝试: ❌ 计数

🌐 分布式架构

系统架构图

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   服务器 A      │    │   服务器 B      │    │   服务器 C      │
│                 │    │                 │    │                 │
│ ┌─────────────┐ │    │ ┌─────────────┐ │    │ ┌─────────────┐ │
│ │ FusionCache │ │    │ │ FusionCache │ │    │ │ FusionCache │ │
│ │ (L1 Cache)  │ │    │ │ (L1 Cache)  │ │    │ │ (L1 Cache)  │ │
│ └─────────────┘ │    │ └─────────────┘ │    │ └─────────────┘ │
└─────────┬───────┘    └─────────┬───────┘    └─────────┬───────┘
          │                      │                      │
          └──────────────────────┼──────────────────────┘
                                 │
                    ┌─────────────▼───────────┐
                    │     Redis Cluster       │
                    │   (分布式缓存 + 消息)    │
                    └─────────────────────────┘

请求处理流程

客户端请求
    ↓
RateLimitMiddleware
    ├─ 检查IP是否被限流
    ├─ 如被限流: 延迟 + 返回429
    └─ 未限流: 继续处理
    ↓
RejectBots 
    ├─ 安全规则检查
    ├─ 发现可疑行为: 调用 RecordBlockAsync()
    └─ 正常请求: 继续处理
    ↓
业务逻辑处理

时间同步

  • 所有服务器使用 UTC 时间
  • 避免时区差异和夏令时问题
  • 确保跨服务器时间计算一致

缓存键设计

缓存键格式: "RateLimit:IP:{IP地址}"
示例: "RateLimit:IP:192.168.1.100"
过期时间: 窗口大小 + 清理间隔(自动管理)

🔍 使用效果演示

正常请求流程

客户端请求 → 检查限流(通过) → 安全检查(通过) → 业务处理 → 返回结果
耗时: 正常业务处理时间(毫秒级)

可疑行为流程

客户端请求 → 检查限流(通过) → 安全检查(拦截) → 记录拦截 → 返回403
耗时: 毫秒级(不处理业务逻辑)

限流封禁流程

客户端请求 → 检查限流(拦截) → 延迟等待 → 返回429
耗时: 2-10秒延迟时间(惩罚机制)

📊 API 接口

核心接口

/// <summary>
/// 基于行为的IP限流服务接口
/// 专注于限制可疑行为,不限制正常请求频率
/// </summary>
public interface IIpRateLimitService
{
    /// <summary>
    /// 检查IP是否被限流
    /// 只检查状态,不记录任何访问信息
    /// </summary>
    Task<RateLimitResult> CheckLimitStatusAsync(
        string ip,
        CancellationToken cancellationToken = default
    );

    /// <summary>
    /// 记录IP被拦截事件
    /// 当安全中间件检测到可疑行为时调用
    /// </summary>
    Task RecordBlockAsync(string ip, string? reason = null);
}

结果对象

/// <summary>
/// 基于行为的限流结果
/// 支持对被限流的请求进行延迟处理
/// </summary>
public class RateLimitResult
{
    /// <summary>是否允许请求</summary>
    public bool IsAllowed { get; init; }

    /// <summary>是否被限流(需要延迟后返回429)</summary>
    public bool IsBlocked { get; init; }

    /// <summary>延迟时间(毫秒)- 仅在被限流时使用</summary>
    public int DelayMs { get; init; }

    /// <summary>结果消息</summary>
    public string Message { get; init; } = string.Empty;

    public static RateLimitResult Allow() => new() { IsAllowed = true };
    
    public static RateLimitResult Block(string message, int delayMs = 0) =>
        new() 
        { 
            IsAllowed = false, 
            IsBlocked = true,
            Message = message,
            DelayMs = delayMs
        };
}

🛡️ 与 RejectBots 集成

集成架构

职责分离:
- RateLimitMiddleware: 专注限流检查和执行
- RejectBots: 专注安全规则检查和拦截记录
- 两者协同工作,实现基于行为的智能限流

RejectBots 集成示例

public class RejectBots
{
    private readonly IIpRateLimitService _rateLimitService;

    public async Task InvokeAsync(HttpContext context)
    {
        var clientIp = GetClientIp(context);
        
        // 检查各种安全规则
        if (IsOldBrowser(context))
        {
            await _rateLimitService.RecordBlockAsync(clientIp, "Old browser blocked");
            await Response403Async(context);
            return;
        }

        if (IsInBlacklist(context))
        {
            await _rateLimitService.RecordBlockAsync(clientIp, "Blacklist hit");
            await Response403Async(context);
            return;
        }

        if (IsEmptyUserAgent(context))
        {
            await _rateLimitService.RecordBlockAsync(clientIp, "Empty User-Agent");
            await Response403Async(context);
            return;
        }

        if (MatchesInterceptRules(context))
        {
            await _rateLimitService.RecordBlockAsync(clientIp, "Custom rule hit");
            await Response403Async(context);
            return;
        }
        
        await _next(context);
    }
}

🔧 高级配置

1. 自定义延迟策略

public class CustomIpRateLimitService : IpRateLimitService
{
    protected override int CalculateBlockedDelay(IpAccessRecord record)
    {
        // 自定义延迟计算逻辑
        var baseDelay = _config.BlockedDelayBaseMs;
        var maxDelay = _config.BlockedDelayMaxMs;
        
        // 基于拦截次数的指数增长
        var multiplier = Math.Pow(2, Math.Min(record.BlockCount - 1, 4));
        var calculatedDelay = (int)(baseDelay * multiplier);
        
        return Math.Min(calculatedDelay, maxDelay);
    }
}

2. 白名单支持

public class WhitelistRateLimitService : IIpRateLimitService
{
    private readonly HashSet<string> _whitelist = new()
    {
        "127.0.0.1", "::1", // 本地地址
        "10.0.0.0/8",       // 内网地址 (需要实现CIDR匹配)
    };
    
    public async Task<RateLimitResult> CheckLimitStatusAsync(
        string ip, 
        CancellationToken cancellationToken = default)
    {
        if (IsWhitelisted(ip))
        {
            return RateLimitResult.Allow();
        }
        
        return await _baseService.CheckLimitStatusAsync(ip, cancellationToken);
    }
    
    public async Task RecordBlockAsync(string ip, string? reason = null)
    {
        if (!IsWhitelisted(ip))
        {
            await _baseService.RecordBlockAsync(ip, reason);
        }
    }
}

3. 监控和诊断

[ApiController]
public class DiagnosticsController : ControllerBase
{
    private readonly IFusionCache _fusionCache;
    
    [HttpGet("rate-limit/status/{ip}")]
    public async Task<IActionResult> GetIpStatus(string ip)
    {
        var cacheKey = $"RateLimit:IP:{ip}";
        var record = await _fusionCache.GetOrDefaultAsync<IpAccessRecord>(cacheKey);
        
        if (record == null)
        {
            return Ok(new { Status = "Clean", Message = "No record found" });
        }
        
        return Ok(new 
        { 
            Status = record.BlockedUntil?.ToString("yyyy-MM-dd HH:mm:ss UTC"),
            BlockCount = record.BlockCount,
            WindowStart = record.WindowStart.ToString("yyyy-MM-dd HH:mm:ss UTC"),
            LastBlockTime = record.LastBlockTime.ToString("yyyy-MM-dd HH:mm:ss UTC")
        });
    }
}

🎯 最佳实践

1. 部署建议

  • 容器化部署: 所有容器使用 UTC 时区
  • 负载均衡: 确保会话粘性不影响限流效果
  • Redis 集群: 使用 Redis 集群保证高可用
  • 监控报警: 监控限流触发频率和Redis连接状态

2. 配置调优

// 开发环境 - 较宽松的配置
WindowSizeMinutes = 10
MaxBlocksPerWindow = 5
BlockDurationMinutes = 15

// 生产环境 - 严格的配置  
WindowSizeMinutes = 5
MaxBlocksPerWindow = 3
BlockDurationMinutes = 30

3. 日志配置建议

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Dpz.Core.Infrastructure.RateLimiting": "Information",
      "FusionCache": "Warning"
    }
  }
}

4. 故障降级策略

public async Task<RateLimitResult> CheckLimitStatusAsync(
    string ip, 
    CancellationToken cancellationToken = default)
{
    try
    {
        return await _normalCheckLogic(ip, cancellationToken);
    }
    catch (Exception ex) when (ex is RedisException or TimeoutException)
    {
        _logger.LogWarning(ex, "限流服务降级,允许通过: {Ip}", ip);
        
        // 降级策略:Redis不可用时允许通过
        return RateLimitResult.Allow();
    }
}

🚀 升级指南

从传统限流升级

  1. 概念转变: 从"频率限流"转为"行为限流"
  2. 配置调整: 移除 MaxRequestsPerWindow 等频率相关配置
  3. 接口变更: CheckAndApplyRateLimitAsync 拆分为 CheckLimitStatusAsyncRecordBlockAsync
  4. 中间件顺序: 确保 RateLimitMiddlewareRejectBots 之前

迁移步骤

// 旧版本调用
var result = await rateLimitService.CheckAndApplyRateLimitAsync(ip);
await rateLimitService.RecordAccessAsync(ip);  // 移除此调用

// 新版本调用  
var result = await rateLimitService.CheckLimitStatusAsync(ip);
// RecordBlockAsync 由 RejectBots 在检测到可疑行为时调用

📈 性能特点

  • 高效检查: 只检查限流状态,不记录正常访问
  • 本地缓存: FusionCache L1 缓存减少 Redis 访问
  • 异步操作: 所有 I/O 操作异步化,提升并发性能
  • 智能降级: Redis故障时自动降级,保证服务可用性
  • 内存友好: 只存储被拦截IP的记录,大幅减少内存使用

🎉 总结

这个基于行为的分布式IP限流服务提供了:

  • 智能限流: 只限制可疑行为,不影响正常用户
  • 分布式支持: 适用于微服务、负载均衡环境
  • 高性能: FusionCache 双层缓存架构
  • 时区安全: 统一使用 UTC 时间
  • 异步架构: 全异步操作,高并发友好
  • 安全延迟: 对攻击者实施延迟惩罚
  • 自动管理: 依赖 FusionCache 自动过期和清理
  • 易于监控: 完整的日志和错误处理

通过这种基于行为的设计,你的应用既能有效防护恶意攻击,又能为正常用户提供无感的高性能体验!

loading