登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

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。

重复 IP 条件集中到命名集合并由单条过滤规则引用的静态结构
图1:地址数据、命名 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。自动合并可以减少这种重复,也能避免重叠区间造成配置加载冲突。

地址形态建议配置适用判断
少量离散 IPtype 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
}

更新前先对输入去重,并明确谁是名单的唯一来源。否则人工命令、配置文件和自动化平台同时写同一集合,虽然规则变少了,数据所有权仍会混乱。

地址清单经过类型边界和区间合并进入 nftables set 的静态维护关系
图2:地址来源、类型边界、区间集合和规则引用之间的静态维护关系;这是说明图,不是执行流程或运行证据。

把预检查设为门禁,避免错误配置直接落地

正式加载前,用 -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 不是必填,但明确上限有助于资源规划。若从数据包路径动态增加元素,官方手册要求为相应场景配置容量上限,并结合超时防止无界增长。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>