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
}
}

如果表和链已经存在,也可以只创建集合。集合名称必须与规则引用一致,地址类型也要匹配;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

若目标是“用新名单完全替换旧名单”,不要把 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 或完整输入文件。
-
273 收藏
-
454 收藏
-
306 收藏
-
158 收藏
-
134 收藏
-
162 收藏
-
128 收藏
-
273 收藏
-
175 收藏
-
418 收藏
-
486 收藏
-
167 收藏
-
448 收藏
-
128 收藏
-
333 收藏
-
117 收藏
-
125 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习