用 nftables named set 可秒级热注入上万黑名单 ip,核心是将 ip 作为动态数据;启用 interval 标志支持 cidr 与自动过期,避免内存暴涨;规则仅写一次,绑定集合后增删自动生效;导入不中断服务,禁用 flush 防放行风险。

用 nftables 的 Named Set 实现秒级热注入上万黑名单 IP,核心是把 IP 当作可动态更新的数据,而非静态规则。集合在内核中以哈希或区间树结构存在,增删元素不触发规则重载,毫秒生效,完全不影响现有连接和流量转发。
创建支持 CIDR 与自动过期的集合
必须启用 interval 标志,否则网段(如 192.168.0.0/16)会被暴力展开成数万个独立地址,导致内存暴涨、加载卡顿、匹配变慢:
- 正确命令:
nft add set inet firewall blacklist { type ipv4_addr \ flags interval \ timeout 24h } -
interval让单 IP(203.0.113.42)和网段(198.51.100.0/24)共存为紧凑区间,查表仍是 O(1) -
timeout 24h表示条目 24 小时后自动删除,无需脚本轮询清理
只写一条规则,全局生效
集合本身不拦截流量,必须绑定到链中才起作用。关键原则是:规则只写一次,后续所有增删都自动生效:
- 先建链并设默认策略为 drop:
nft add chain inet firewall input { type filter hook input priority 0 \; policy drop \; } - 再加唯一拦截规则:
nft add rule inet firewall input ip saddr @blacklist drop - 该规则位置建议放在白名单(如 SSH、HTTP 放行)之前,确保恶意 IP 在第一层就被截断
批量导入上万 IP,不中断服务
导入过程全程在线,零丢包、零 reload、零连接中断。推荐使用 shell 循环逐行加载,稳定且可控:
- 从文件导入(每行一个 IP 或 CIDR):
while IFS= read -r ip; do [[ -n "$ip" ]] && nft add element inet firewall blacklist { "$ip" }; done - 导入 1 万个条目通常在 1–3 秒内完成,内核直接追加到哈希表,无锁竞争
- 验证进度:
nft list set inet firewall blacklist | wc -l查当前条目数
避免清空导致放行风险
切勿使用 nft flush set 清空集合——这会瞬间移除全部条目,造成短暂但危险的放行窗口:
- 安全做法:依赖
timeout自动回收;或用nft delete element精准移除个别 IP - 如需整体重置,可新建集合
blacklist_v2,导入新数据后,修改规则引用:nft replace rule inet firewall input handle 1 ip saddr @blacklist_v2 drop - 确认规则是否生效:
nft list chain inet firewall input和nft list set inet firewall blacklist











