nftables动态集合实现毫秒级ip封禁,需启用interval标志支持单ip与cidr混存,配合timeout自动清理、size合理预分配,并在input链前置规则引用集合查表丢包。

用 nftables 动态集合实时更新封禁 IP 列表,核心是把黑名单变成内核级可高速查表的数据结构,而不是堆砌规则。它支持毫秒级生效、自动过期、运行时增删,且不中断服务。
创建带超时和网段支持的集合
必须启用 interval 标志才能混存单 IP(如 192.0.2.5)和 CIDR 网段(如 198.51.100.0/24),否则 /24 会被拆成 256 条独立记录,性能骤降:
- nft add set inet firewall blacklist { type ipv4_addr \ flags interval \ timeout 1h \ size 262144 }
- size 值建议设为预期最大条目数的 2–4 倍,避免哈希冲突拖慢匹配
- timeout 保证封禁自动清理,无需脚本定时 flush
链中只写一条引用规则
集合本身不拦截流量,必须配合链中规则触发查表。这条规则要放在 input 链靠前位置(早于 accept 规则):
- nft add chain inet firewall input { type filter hook input priority 0 \; policy drop \; }
- nft add rule inet firewall input ip saddr @blacklist drop
- 内核收到包后直接查 @blacklist,命中即丢,不走后续规则
安全地动态增删 IP
所有操作均可热执行,但要避开“清空再重载”这种危险方式——nft flush set 会导致短暂放行窗口:
- 加单个 IP:nft add element inet firewall blacklist { 203.0.113.42 }
- 加网段:nft add element inet firewall blacklist { 192.0.2.0/24 }
- 批量导入(从文件):
while read ip; do nft add element inet firewall blacklist { $ip }; done - 临时封禁(10 分钟):nft add element inet firewall blacklist { 198.51.100.22 timeout 10m }
对接外部信号实现自动封禁
集合只是执行终点,识别扫描或攻击行为需外部联动:
- 速率突增:用 limit + counter 记录每 IP 每秒连接数,脚本每 5 秒检查,超阈值写入集合
- TCP 异常:匹配
tcp flags & (syn | ack) == syn ct state invalid,3 秒内 5 次即封 - HTTP 日志:Nginx 记录 404 /wp-admin/ 或 400 /api/v1/login,用 Python 或 fail2ban 解析 access.log 提取 remote_addr 写入
- 务必加日志前缀,例如
log prefix "SCAN-AUTO:" level warn,便于回溯验证











