- 工信部备案号 滇ICP备05000110号-1
- 滇公网安备53011102001527号
- 增值电信业务经营许可证 B1.B2-20181647、滇B1.B2-20190004
- 云南互联网协会理事单位
- 安全联盟认证网站身份V标记
- 域名注册服务机构许可:滇D3-20230001
- 代理域名注册服务机构:新网数码
- CN域名投诉举报处理平台:电话:010-58813000、邮箱:service@cnnic.cn
在公有云部署高流量 Web 服务时,遭遇 CC 攻击或凭证爆破需秒级封禁恶意源 IP。传统 Nginx 基于 deny 192.0.2.0/24; 的静态配置,每次封禁均需 nginx -s reload。云主机上频繁 reload 会触发 master 重新 fork worker,旧 worker 停留优雅退出期,短连接突增时引发 worker_connections 翻倍占用与 TCP TIME_WAIT 堆积,造成 P99 延迟毛刺与内存拷贝开销。
解决思路其一为内核层 ipset 动态拦截。相较于直接操纵 iptables 链式规则(超千条规则遍历导致软中断飙升),ipset 基于哈希表,查找复杂度为 O(1):
ipset create blacklist hash:ip timeout 3600
iptables -I INPUT -m set --match-set blacklist src -j DROP
当威胁情报平台或自研风控捕获恶意 IP,直接通过 ipset 添加,无需触动任何用户态进程:
ipset add blacklist 192.0.2.66 timeout 1800
在 K8s 集群节点上,利用 DaemonSet 运行 ipset 同步器,将外部 API 的恶意 IP 推送至宿主机 set。需注意云环境常启用 conntrack,若攻击已建立连接,需一并清除会话避免残留通道:
conntrack -D -s 192.0.2.66
若业务必须基于七层特征在 Nginx 层封禁,且前端云 LB 已透传 X-Forwarded-For,采用 OpenResty 动态字典实现完全零 Reload。在 nginx.conf 定义共享内存并在 http 块还原真实客户端 IP:
lua_shared_dict ip_blacklist 50m;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
set_real_ip_from 10.0.0.0/8;
编写 Lua 脚本定时从 Redis 或威胁情报接口拉取最新恶意 IP 段,存入共享字典。处理请求阶段直接拦截:
local ip = ngx.var.remote_addr
local blacklist = ngx.shared.ip_blacklist
if blacklist:get(ip) then
ngx.log(ngx.ERR, "blocked malicious ip: ", ip)
return ngx.exit(444)
end
为避免 Lua 每次请求都查远端 Redis 造成 RT 升高,采用 ngx.timer.every 后台轮询更新,请求阶段仅内存哈希读取。实测在 16 核云主机上,百万级 IP 字典查找耗时低于 0.1ms,且配置变更对线上长连接零感知。
面对云上弹性伸缩组,新扩容实例若依靠启动脚本拉取全量黑名单,存在分钟级窗口期失防。进阶做法是利用 nftables 原生集合与云元数据结合。较新内核(5.x+)推荐使用 nftables 替代 iptables + ipset 组合,原生支持带超时的集合与字典类型,规避 iptables 规则链表化带来的线性匹配损耗:
nft add table inet filter
nft add set inet filter blacklist { type ipv4_addr \\; flags timeout \\; }
nft add rule inet filter input ip saddr @blacklist drop
动态封禁只需一条命令且支持自动过期:
nft add element inet filter blacklist { 192.0.2.66 timeout 1h }
对于需封禁整个 CIDR 段的场景,将 set 类型改为 type ipv4_addr . inet_service 可针对特定端口精细化限杀,例如仅封禁恶意 IP 对 3306 的暴破而放行其对 443 的回源,减少误杀正常爬虫。
售前咨询
售后咨询
备案咨询
二维码

TOP