真正有效的CC防护需用OpenResty+Redis实现毫秒级动态黑白名单,避免Nginx重载中断、配置臃肿和误伤业务,支持自动封禁与过期清理。

靠手动加 deny 规则防 CC 攻击,已经跟不上攻击节奏了。真正有效的做法是把黑白名单从配置文件里“搬出来”,放到内存数据库里实时管理,再通过 Lua 脚本在请求入口做毫秒级判断。
为什么静态黑名单撑不住 CC 攻击
当攻击者用上万代理 IP 轮流发请求,或者把单 IP 请求频率压在限流阈值边缘时,传统方式就暴露三个硬伤:
- 规则更新要 reload Nginx,每次至少 10–15 秒中断,攻击早就完成一轮数据抓取
- 黑名单超 500 条后,Nginx 启动时间明显变慢,配置维护也容易出错
- 无法区分“真实用户抢券”和“脚本批量刷接口”,一刀切封禁会误伤业务
动态黑白名单的核心组件
这套机制不依赖复杂中间件,用 OpenResty(Nginx + LuaJIT)配合 Redis 就能落地:
-
OpenResty:在
access_by_lua_block阶段执行逻辑,不经过后端服务,延迟低于 1ms -
Redis:存 IP 状态(如
black:192.168.1.100→1),支持过期时间自动清理 - 日志分析模块:从 access.log 或实时流中识别高频异常行为(比如 1 分钟内调用登录接口 50 次)
典型自动化封禁流程
不需要人工干预,整个过程可闭环运行:
- 某 IP 在 60 秒内触发 /api/login 超过 30 次 → 日志分析服务写入 Redis:
SET black:203.0.113.45 1 EX 3600 - 下一次请求到达时,Lua 脚本读取
GET black:203.0.113.45,命中即返回 403 - 封禁一小时后自动过期,无需人工解封;若需提前解除,直接删 Redis key 即可
- 白名单同理,用
whitelist:前缀,优先级高于黑名单,适合运维跳板机或合作方系统
绕过 CDN 导致封禁失效怎么办
如果用了 CDN 或反向代理,$remote_addr 只会是 CDN 节点 IP。必须改用真实客户端 IP:
- 确认 CDN 在请求头里传了
X-Forwarded-For或X-Real-IP - Nginx 配置中加:
set $client_ip $remote_addr;,再根据 header 覆盖:if ($http_x_forwarded_for) { set $client_ip $http_x_forwarded_for; } - Lua 脚本里查 Redis 时,统一用
$client_ip,避免封错


















