nftables set 怎么为大量 IP 规则减少重复配置
来源:17golang原创
时间:2026-10-06 06:05:24 439浏览 收藏
大量 IP 规则不该靠复制粘贴维护。更稳妥的做法是把地址集中放进一个命名 set,规则里只写一次 ip saddr @blocked_ipv4。以后新增或删除 IP 时只改集合元素,不再复制整条匹配与动作,规则数量、漏改概率和审计成本都会下降。
下面用一个入口访问控制场景拆开说明:需要拒绝一批来源 IPv4 地址,其中既有单个地址,也有网段;地址列表会持续变化,但过滤动作始终是 drop。
先划清边界:规则负责动作,set 负责地址数据
如果把每个 IP 写成一条规则,地址与动作会被绑在一起。三十个地址就是三十次重复,后续把 drop 改成 counter drop 时也要改三十处。命名 set 将这两部分拆开:
- set 保存同一种数据类型的元素,例如
ipv4_addr; - rule 只表达一次匹配和动作,例如“来源地址属于该集合就丢弃”;
- 元素维护命令 独立增删地址,不必重建引用它的规则。
匿名集合适合少量且固定的值,例如端口 { 22, 443 };它绑定在规则上,不能在绑定后单独更新。地址较多或经常变化时,应使用带名称的 set。

准备权限和对象:类型先于元素
维护 nftables 通常需要 root 权限或等价的 CAP_NET_ADMIN 能力。不要把 IPv4、IPv6、端口混进同一个集合:集合的 type 决定了允许保存和匹配的数据。本文的来源地址集合使用 ipv4_addr,IPv6 应另建 ipv6_addr 集合。
一个可持久化的最小配置如下:
table inet access_control {
set blocked_ipv4 {
# 集合只保存 IPv4 地址和网段
type ipv4_addr
flags interval
auto-merge
elements = {
198.51.100.23,
203.0.113.0/24
}
}
chain input {
# 绑定输入钩子;默认策略按现网要求设置
type filter hook input priority filter; policy accept;
# 规则只引用一次命名集合,成员变化不需要复制规则
ip saddr @blocked_ipv4 counter drop
}
}
inet 表可以容纳 IPv4 与 IPv6 规则,但 blocked_ipv4 自身仍是明确的 IPv4 类型。这个边界能避免把看似相近、实际类型不同的数据塞进同一份清单。
让大量地址变短:interval 与 auto-merge 怎么选
如果集合只保存离散单个 IP,普通 ipv4_addr set 就够了。只要出现 CIDR、地址区间,或希望相邻与重叠范围自动合并,就应启用 flags interval。auto-merge 只对 interval set 有效,它会在加载时合并相邻或重叠的元素。
例如 203.0.113.0/24 已经覆盖其中的单个地址,就没有必要再保存 203.0.113.8。自动合并可以减少这种重复,也能避免重叠区间造成配置加载冲突。
| 地址形态 | 建议配置 | 适用判断 |
|---|---|---|
| 少量离散 IP | type ipv4_addr | 没有 CIDR 或范围 |
| 网段、范围 | flags interval | 元素含 CIDR 或起止区间 |
| 大量重叠网段 | interval + auto-merge | 希望加载时合并覆盖关系 |
| 临时封禁 | flags timeout | 元素应在到期后自动移除 |
不要随手添加 constant。它表示集合绑定后内容不应变化,与“地址名单经常增删”的目标相冲突。由数据包路径动态写入集合又是另一类设计,需要 dynamic、容量上限与超时控制,不能直接套用本文的人工或自动化清单维护方式。
批量更新元素,不再改动过滤规则
命名 set 的价值在于成员可以独立维护。一次加入多个地址:
# 批量加入三个离散地址;表名和集合名必须与现有配置一致
sudo nft add element inet access_control blocked_ipv4 \
'{ 192.0.2.10, 192.0.2.11, 192.0.2.12 }'
# 只删除已解除封禁的地址,不触碰引用集合的过滤规则
sudo nft delete element inet access_control blocked_ipv4 \
'{ 192.0.2.11 }'
如果名单来自配置管理系统,建议让自动化产出完整的 nft 脚本,再统一加载,而不是在循环中逐条执行命令。这样一批改动要么整体通过,要么不落地,失败时也容易定位到同一份输入文件。
# 文件片段:集中描述本批次需要增加的元素
add element inet access_control blocked_ipv4 {
192.0.2.20,
192.0.2.21,
198.51.100.0/25
}
更新前先对输入去重,并明确谁是名单的唯一来源。否则人工命令、配置文件和自动化平台同时写同一集合,虽然规则变少了,数据所有权仍会混乱。

把预检查设为门禁,避免错误配置直接落地
正式加载前,用 -c 只检查命令有效性,不应用变更。检查通过后再用同一文件加载:
# 先检查语法、对象引用和元素类型,不修改当前规则集 sudo nft -c -f /etc/nftables.conf # 检查成功后再加载同一份文件,避免检查对象与发布对象不一致 sudo nft -f /etc/nftables.conf # 只查看目标集合,确认成员是否符合本次变更单 sudo nft list set inet access_control blocked_ipv4
这里的门禁重点不是“命令返回零就万事大吉”,而是保证检查和加载使用同一份文件,并在变更记录中保留集合名、元素来源、预期新增/删除数量和回退版本。对于远程主机的防火墙变更,还要预留独立管理通道,避免误伤当前 SSH 来源。
常见失败怎么定位
提示数据类型不匹配
先检查 set 的 type,再检查加入的元素。IPv6 地址不能写入 ipv4_addr,端口也不能写入地址集合。最直接的修复是按类型拆集合,而不是把所有条件改成字符串。
提示区间冲突
集合含网段或范围时确认是否启用了 interval。如果输入中有相邻、重叠或“网段已经覆盖单点”的情况,使用 auto-merge 或在上游先规范化地址清单。
元素改了但流量行为没变
检查规则是否真的引用了正确的表、集合和地址方向。ip saddr 匹配来源地址,ip daddr 匹配目的地址;表名相同但 family 不同,也不是同一个对象。还要留意更早命中的 accept/drop 规则是否已经决定了结果。
集合越来越大
静态名单要建立删除机制;临时名单应考虑 timeout。如果从数据包路径动态增加元素,必须设置 size 和超时,防止无限增长。超时元素的内存回收还受 gc-interval 影响,不能只看“逻辑上已经过期”。
维护清单:把 set 当成可审计的数据对象
- 一个 set 只保存一种明确类型和一种业务含义;
- IPv4、IPv6、端口分别建集合,不用名字相近掩盖类型差异;
- 网段使用
interval,重叠清单按需启用auto-merge; - 规则只引用集合,名单更新不复制匹配与动作;
- 检查与加载使用同一份文件,变更前保留可回退版本;
- 记录元素来源、责任人和过期策略,避免多个系统争抢写入权;
- 定期列出目标 set,复盘是否仍需要每个地址或网段。
最终效果并不是“把很多 IP 换一种写法”这么简单,而是把防火墙规则拆成稳定的策略层和可更新的数据层。策略层保持一条清晰规则,数据层通过命名 set 批量维护,新增、删除、检查和回退都有明确入口。
相关问题
set 和 map 有什么区别?
set 主要回答“这个键是否存在”;map 则把键映射到一个值或 verdict。只做 IP 白名单、黑名单时优先用 set,需要不同地址映射到不同动作时再考虑 map。
可以在 inet 表中混合 IPv4 和 IPv6 吗?
表可以使用 inet family,但集合仍有具体元素类型。实际维护时分别创建 ipv4_addr 和 ipv6_addr 集合,规则分别用 ip 与 ip6 表达式引用。
元素很多时要不要设置 size?
由用户态命令加入元素时,size 不是必填,但明确上限有助于资源规划。若从数据包路径动态增加元素,官方手册要求为相应场景配置容量上限,并结合超时防止无界增长。
-
426 收藏
-
387 收藏
-
242 收藏
-
238 收藏
-
402 收藏
-
321 收藏
-
294 收藏
-
233 收藏
-
166 收藏
-
426 收藏
-
243 收藏
-
132 收藏
-
395 收藏
-
231 收藏
-
470 收藏
-
306 收藏
-
362 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习