窗口期 IP 限流
基于可疑事件窗口计数的分布式 IP 限流,只限制可疑行为,不影响正常请求频率。 IP 只作为同一来源的行为聚合键,不作为可信身份或白名单依据。
核心思路
可疑事件(规则命中 / 空 UA / 低版本浏览器 / 404 等)
↓ 调用 RecordEventAsync 计数
窗口内事件数 ≥ MaxEvents
↓
封禁 IP BlockMinutes 分钟,封禁期内所有请求延迟 BlockDelaySeconds 后返回 429
- 正常请求不做任何计数,不限制频率
- 事件记录存在 FusionCache(L1 内存 + L2 Redis),多服务器共享封禁状态
- 事件更新使用分布式锁串行化,避免并发请求丢失窗口计数
- 缓存键格式:
RateLimit:Window:{IP},如RateLimit:Window:192.168.1.100
配置
配置节 RateLimit,所有字段可选,未配置时使用默认值:
{
"RateLimit": {
"WindowMinutes": 5,
"MaxEvents": 3,
"BlockMinutes": 30,
"BlockDelaySeconds": 2
}
}
| 字段 | 默认值 | 说明 |
|---|---|---|
WindowMinutes | 5 | 统计窗口(分钟),窗口过期后计数清零 |
MaxEvents | 3 | 单个窗口内的事件数阈值,达到即封禁 |
BlockMinutes | 30 | 封禁时长(分钟) |
BlockDelaySeconds | 2 | 封禁期内每个请求的延迟响应(秒),增加攻击成本 |
使用
// 注册服务(绑定 RateLimit 配置节)
services.AddIpRateLimit(configuration);
// 管线中添加中间件
// 注意:必须放在 UseAuthentication 之后,已登录用户才能正常放行
app.UseIpRateLimit();
事件来源
RecordEventAsync(ip, reason) 由以下组件调用:
| 组件 | 事件 |
|---|---|
BotProtectionMiddleware | 拦截规则命中、空 UA、低版本浏览器 |
AuthStatusPageMiddleware(Auth) | 404 请求 |
RejectBotsMiddleware(Web) | 黑名单命中、404 请求 |
已登录用户、开发环境、IgnoreRequestPrefix 忽略前缀的请求不参与限流。
故障降级
限流服务访问缓存(Redis)失败时自动放行请求并记录警告日志, 避免限流组件故障导致全站不可用。
机器人拦截
规则判定由 Dpz.Core.Infrastructure.BotProtection 提供, 检测项按应用开关(见 BotProtectionOptions):
- Web:拦截规则 + 空 UA + 低版本浏览器(需先
UseDetection) - Auth:仅拦截规则(认证客户端复杂,不做 UA/浏览器判定)
AI 正在分析代码…
评论加载中...