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

nftables 怎样按集合更新允许的地址

来源:17golang原创

时间:2026-10-24 22:43:17 372浏览 收藏

nftables 更新允许地址的关键是使用命名集合(named set),让规则引用集合名,而不是把地址直接写进规则。日常只需对集合执行 add element 或 delete element,不会因为增删一个地址而重建整条放行规则。

官方手册地址:https://www.netfilter.org/projects/nftables/manpage.html。下面以 IPv4 白名单 allowed_hosts 为例,命令均是配置示例,重点是理解对象层级和影响范围。

先创建可变的 named set,再让规则引用 @allowed_hosts;单个地址变化用 add/delete element,只有确认要清空时才用 flush set。

先创建命名集合,让规则只引用集合名

集合属于表,规则属于链。下面的 nft 配置把它们放在同一个 inet firewall 表中:集合的数据类型是 ipv4_addr,输入链只允许来源地址命中集合的 SSH 请求,其余流量仍由链策略决定。

table inet firewall {
    # 允许地址放在命名集合中,后续可以单独增删成员。
    set allowed_hosts {
        type ipv4_addr
    }

    chain input {
        # 仅示例:实际默认策略应结合现有管理入口谨慎设置。
        type filter hook input priority filter; policy drop;
        # @allowed_hosts 表示引用集合,而不是写死某个地址。
        ip saddr @allowed_hosts tcp dport 22 accept
    }
}
nftables 表、输入链、允许地址集合与规则引用关系的静态结构图
图1:静态结构说明图。规则侧通过 @allowed_hosts 读取集合,管理侧只需要维护集合成员。

如果表和链已经存在,也可以只创建集合。集合名称必须与规则引用一致,地址类型也要匹配;IPv6 地址应另建 ipv6_addr 类型的集合,不能混入 IPv4 集合。

增加或删除地址时只改集合成员

命名集合创建后,用 add element 加入一个或多个地址,用 delete element 移除不再允许的地址。花括号在 shell 中容易被展开,建议整体加引号。

# 追加一个临时获准的来源地址,不改变引用它的规则。
sudo nft add element inet firewall allowed_hosts '{ 203.0.113.10 }'

# 一次追加多个地址,元素类型仍必须是 ipv4_addr。
sudo nft add element inet firewall allowed_hosts '{ 198.51.100.20, 198.51.100.21 }'

# 撤销一个地址的允许资格,只删除该集合成员。
sudo nft delete element inet firewall allowed_hosts '{ 198.51.100.21 }'

这里的地址使用文档示例网段,实际部署应替换为已经确认并获准的地址。add 适合增量变更;当成员已存在或集合类型、表名写错时,应保留命令错误并先确认对象,不要把错误当成“地址已经放行”。

list、get 和 flush 的作用并不相同

更新前先读取集合内容,可以减少误删。list set 查看整个集合,get element 判断某个地址是否存在;flush set 则会清空集合中的所有成员,影响范围远大于删除单个元素。

# 查看集合定义及当前成员,确认表、集合名和地址类型。
sudo nft list set inet firewall allowed_hosts

# 查询某个地址是否是集合成员,适合做单点判断。
sudo nft get element inet firewall allowed_hosts '{ 203.0.113.10 }'

# 仅在明确要撤销全部允许地址时使用;它不会删除集合定义。
sudo nft flush set inet firewall allowed_hosts
nftables 集合增删、查询和清空命令作用范围的静态关系图
图2:静态边界说明图。add/delete 触碰成员,list/get 读取状态,flush 直接清空集合内容。

若目标是“用新名单完全替换旧名单”,不要把 flush 加几条命令当成无风险更新:中间可能出现空集合。可以把完整变更写入 nft 输入文件后用 nft -f 一次提交,并在提交前确认文件只包含预期表、链和集合对象。

timeout、constant 和整批替换的边界

带 timeout 的集合可以让成员在指定时间后过期,添加元素时可以附带 timeout 1h。这种方式适合临时白名单,但过期时间不是永久授权;排查时要看集合输出中的剩余时间。

# 仅对带 timeout 标志的集合设置一个小时的成员有效期。
sudo nft add element inet firewall allowed_hosts '{ 203.0.113.10 timeout 1h }'

# 读取规则集,确认成员、timeout 和 expires 等状态字段。
sudo nft list ruleset

constant 集合不能在绑定规则后随意改变;匿名集合也不能像 named set 一样单独维护。遇到“集合存在但不能 add/delete”的报错,先看它是匿名集合、constant 集合,还是表族和地址类型不匹配,再决定是否需要调整配置结构。

几个容易混淆的问题

修改集合后要重新加载整份规则吗? 增删命名集合成员通常不需要重写引用规则;如果修改的是集合定义、链或规则结构,才需要按现有发布流程加载变更。

为什么 add element 成功却仍然无法连接? 集合只影响引用它的规则,还要检查实际命中的链、端口、协议、地址族、默认策略以及其他更早的拒绝规则。

删除集合成员会删除规则吗? 不会。删除的是集合中的元素;规则仍然存在,只是该地址不再满足 ip saddr @allowed_hosts。

实际维护时可以记住一句话:先用 list 确认对象,再用最小范围的 add/delete element 修改;只有明确清空或整批替换时,才考虑 flush 或完整输入文件。

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