如何通过NFTables集合高效处理数万恶意IP规则?
- 内容介绍
- 相关推荐
本文共计596个文字,预计阅读时间需要3分钟。
使用nftables的集合(Set)管理数百万恶意IP,核心并非堆规则,而是将IP列表转化为内核快速查找的数据结构。底层使用哈希或区间树实现,查找复杂度接近O(1),比逐条匹配快几数量级。
选对集合类型:ipv4_addr + interval 是黑名单标配
恶意IP常含网段(如192.168.0.0/16)和单IP混用,必须启用 interval 标志:
-
错误写法:
nft add set inet firewall blacklist { type ipv4_addr }—— 不支持CIDR,/24网段会被拆成256个独立IP,内存暴涨、性能骤降 -
正确写法:
nft add set inet firewall blacklist { type ipv4_addr \ flags interval \ timeout 24h }—— 支持192.168.1.0/24、10.0.5.7等混合输入,超时自动清理
规则链中只写一次引用,不重复匹配
集合必须配合链中的“匹配动作”使用,且只需一条规则覆盖全部IP:
- 先创建基础链(默认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 - 这条规则生效后,内核在收到包时直接查
@blacklist这个集合,命中即丢弃,无需遍历上万条规则
动态增删IP:脚本化操作不中断服务
集合元素可运行时修改,适合对接威胁情报源或自动封禁脚本:
- 加一个IP:
nft add element inet firewall blacklist { 203.0.113.42 } - 加一个网段:
nft add element inet firewall blacklist { 198.51.100.0/24 } - 批量导入(从文件):
while read ip; do nft add element inet firewall blacklist { $ip }; done < blacklist.txt - 注意:不要用
nft flush set清空再重载——会短暂放行;应逐条删除或依赖timeout自动过期
搭配Map做分级响应(进阶用法)
如果不同IP需不同处理(如封1小时 vs 永久拉黑),可用Map替代纯Set:
- 建Map映射IP到动作:
nft add map inet firewall ip_action { type ipv4_addr : verdict \; } - 设置策略:
nft add element inet firewall ip_action { 192.0.2.100 : drop, 192.0.2.101 : reject with icmp type host-unreachable } - 在链中调用:
nft add rule inet firewall input meta nftrace set 1 ip saddr @ip_action
本文共计596个文字,预计阅读时间需要3分钟。
使用nftables的集合(Set)管理数百万恶意IP,核心并非堆规则,而是将IP列表转化为内核快速查找的数据结构。底层使用哈希或区间树实现,查找复杂度接近O(1),比逐条匹配快几数量级。
选对集合类型:ipv4_addr + interval 是黑名单标配
恶意IP常含网段(如192.168.0.0/16)和单IP混用,必须启用 interval 标志:
-
错误写法:
nft add set inet firewall blacklist { type ipv4_addr }—— 不支持CIDR,/24网段会被拆成256个独立IP,内存暴涨、性能骤降 -
正确写法:
nft add set inet firewall blacklist { type ipv4_addr \ flags interval \ timeout 24h }—— 支持192.168.1.0/24、10.0.5.7等混合输入,超时自动清理
规则链中只写一次引用,不重复匹配
集合必须配合链中的“匹配动作”使用,且只需一条规则覆盖全部IP:
- 先创建基础链(默认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 - 这条规则生效后,内核在收到包时直接查
@blacklist这个集合,命中即丢弃,无需遍历上万条规则
动态增删IP:脚本化操作不中断服务
集合元素可运行时修改,适合对接威胁情报源或自动封禁脚本:
- 加一个IP:
nft add element inet firewall blacklist { 203.0.113.42 } - 加一个网段:
nft add element inet firewall blacklist { 198.51.100.0/24 } - 批量导入(从文件):
while read ip; do nft add element inet firewall blacklist { $ip }; done < blacklist.txt - 注意:不要用
nft flush set清空再重载——会短暂放行;应逐条删除或依赖timeout自动过期
搭配Map做分级响应(进阶用法)
如果不同IP需不同处理(如封1小时 vs 永久拉黑),可用Map替代纯Set:
- 建Map映射IP到动作:
nft add map inet firewall ip_action { type ipv4_addr : verdict \; } - 设置策略:
nft add element inet firewall ip_action { 192.0.2.100 : drop, 192.0.2.101 : reject with icmp type host-unreachable } - 在链中调用:
nft add rule inet firewall input meta nftrace set 1 ip saddr @ip_action

