写好 nftables 规则集关键在“准”和“快”:高频 established/related 流量须顶置放行,invalid 状态紧随其后秒拒;用 map 替代线性规则实现 o(1) 查找;按 fastpath、policy、fallback 三层分链结构化设计;log 和 counter 须严格限条件,避免性能损耗。

写好 nftables 规则集,关键不在“多”,而在“准”和“快”:高频流量要秒放,非法状态要秒拒,策略逻辑要分层,日志计数要克制。规则不是堆出来的,是结构设计出来的。
高频连接优先放行
ESTABLISHED/RELATED 连接通常占实际入站流量 70% 以上,它们不该参与任何业务策略判断。必须把这条规则放在 input 或 forward 链最顶端:
- nft add rule inet filter input ct state { established, related } accept
- 紧随其后建议加一条:nft add rule inet filter input ct state invalid drop,快速过滤掉非法连接状态,避免后续误匹配
- 不要把它混在一堆端口放行规则中间——哪怕只晚一行,CPU 就得多做一次 conntrack 状态检查
用 map 替代长链式规则
当 IP 黑名单超过几百条、端口白名单超过几十个时,线性遍历规则会显著拖慢匹配速度。map 提供 O(1) 查找性能,适合大规模策略:
- 创建映射:nft add map inet filter ip2verdict { type ipv4_addr : verdict \; size 65536 \; }(size 预设容量,防运行时扩容抖动)
- 注入策略:nft add element inet filter ip2verdict { 192.0.2.100 : drop, 198.51.100.20 : accept }
- 链中调用:nft add rule inet filter input ip saddr @ip2verdict
- 不推荐用 set + if 语句替代 map,后者仍需遍历;map 是真正哈希查表
按意图分层拆解链结构
别把所有规则塞进一条 input 链。按处理目标划分为三层,每层专注一件事:
- fastpath 链:只做轻量级判断——lo 接口、conntrack 状态、管理网段(如 10.0.0.0/8)放行,80% 流量在此终止
- policy 链:挂载 map、concat、命名 set 等结构化策略,面向租户、服务或接口维度做精细化控制
- fallback 链:仅保留 drop 或 limit 类兜底动作,不掺杂任何 ACCEPT 或 log,确保路径干净、延迟可控
慎用 log 和 counter
log 和 counter 在高并发下会频繁触发软中断、内存写入与缓存刷新,是隐形性能杀手:
- log 仅用于临时调试,生产环境若必须启用,务必加严格条件:tcp dport 22 ct state new,并带 prefix 如 "SSH-ATTEMPT: "
- counter 除非用于限速(如 limit rate 5/minute)或告警联动,否则一律移除;nft list ruleset -a 才显示计数器,不影响运行时性能
- 长期统计需求请绕过 netfilter:用 eBPF map 统计连接行为,或通过 /proc/net/nf_conntrack 获取连接跟踪摘要











