用nftables map实现千万级连接秒级过滤的关键在于结构设计与内核查找优化:选用ipv4_addr等固定长度key、显式指定size、分层构建专用map、规则前置插入、配合conntrack及自动化超时更新。

用 nftables 的 Map 实现千万级连接的秒级过滤,关键不在堆数量,而在结构设计与内核查找路径优化。Map 本身不处理连接,而是把 IP、端口等作为 key 映射到动作(如 drop/accept),配合 conntrack 和高效匹配逻辑,才能在高并发下保持亚毫秒响应。
选对 key 类型和底层结构
IPv4 地址类 key(如 ipv4_addr)默认走内核哈希表,查找复杂度稳定 O(1);而带掩码的 network + prefix 或变长字段容易退化为线性扫描。
- 优先用固定长度类型:ipv4_addr、inet_service,避免混用 inet_prefix
- 创建 Map 时显式指定 size,例如
size 2000000,防止运行中扩容引发哈希冲突上升 - 不用字符串解析类 key(如 hostname),所有 key 必须是二进制可哈希值
分层设计多个专用 Map
一个大 Map 硬扛千万条目不可取,应按用途拆分为小而专的映射表,各司其职:
- IP 黑名单 Map:type ipv4_addr : verdict,用于威胁情报自动同步,支持原子增删
- IP+端口限速 Map:type ipv4_addr . inet_service : counter,记录每个客户端对特定服务(如 443)的当前连接数,配合 meter 规则动态限流
- 可信会话状态 Map:type ipv4_addr . inet_service : ct state,预加载高频合法会话特征,跳过 conntrack 全流程,直接放行 ESTABLISHED 流量
嵌入规则链并保障命中效率
Map 规则必须放在链的靠前位置,且使用 insert rule 而非 append,确保优先匹配、快速终止。
- 示例命令:
nft insert rule inet filter input ip saddr @blacklist_map counter name blacklist_hit drop - 务必开启 counter,便于验证是否真实命中 Map,而非 fallback 到后续规则
- 禁用日志(log)、关闭动态 key 创建(如 auto-learn)、避免在 Map 规则后接复杂 match,防止 pipeline 拖慢
配合 conntrack 与自动化更新
Map 是静态索引结构,需结合 conntrack 做状态识别,并由外部脚本驱动动态更新:
- 用
ct state new limit rate 10/second标记高频新建连接的源 IP - 脚本监听 nft counters 或 ulogd2 日志,提取可疑 IP 后执行:
nft add element inet filter badhosts { 192.0.2.100 timeout 5m } - 超时机制(timeout)让黑名单自动清理,避免人工干预,也防止误封长期有效 IP











