Linux nftables sets timeout怎样让临时规则自动过期
来源:17golang原创
时间:2026-11-05 03:09:09 134浏览 收藏
Linux nftables 的临时规则,通常不应该靠定时脚本逐条删除。更直接的做法是把临时地址或端口放进带超时能力的 named set:集合声明 flags timeout,加入元素时写 timeout 10s 这类时长,元素到期后就会自动从集合中移除,引用该集合的规则也随之不再匹配它。
要让临时元素自动过期,关键不是给规则本身加一个倒计时,而是给 set 开启flags timeout,再给每个元素设置timeout。查看集合时,expires表示当前剩余时间。
官方地址:https://wiki.nftables.org/wiki-nftables/index.php/Sets
flags timeout是集合能力声明;没有它,元素不能按超时方式加入。- 集合级
timeout可以提供默认生命周期,加入元素时也可以显式覆盖。 expires是倒计时状态,不是要写回配置文件的固定值;到期后元素会被清理。
为什么 nftables 的临时规则要放进 set
如果临时地址直接散落在多条规则里,添加、删除和审计都容易变成脚本拼接问题。named set 可以让规则只负责引用一组值,例如使用 @temp_block 匹配来源地址;临时状态则集中由集合维护。
nftables 官方 Sets 文档把 timeout 解释为元素在集合中保留的时间,时间值可以使用秒、分钟、小时等单位组合。这里的“自动过期”针对的是集合元素,不是让整个表或规则链自动消失。
图 1 把四个容易混淆的对象分开:flags timeout 打开能力,元素级 timeout 提供生命周期,expires 表示倒计时,规则通过 set 查找决定是否匹配。

先创建一个带超时能力的地址集合
下面用独立的 inet 表和集合演示。示例中的地址是文档保留地址,只用于说明语法;生产环境应替换为自己的业务对象,并确认不会误封管理入口。
# 创建一个同时支持 IPv4/IPv6 规则的演示表。
nft add table inet fw_demo
# 声明 IPv4 地址集合,并允许集合元素携带超时信息。
nft add set inet fw_demo temp_block {
type ipv4_addr
flags timeout
}
# 添加一条临时地址,10 秒后从 temp_block 中移除。
nft add element inet fw_demo temp_block { 198.51.100.23 timeout 10s }
这里有三个关键点。第一,type ipv4_addr 决定元素类型;第二,flags timeout 只是在集合层打开超时能力;第三,真正的生命周期由元素后的 timeout 10s 指定。
如果希望同一个集合有默认时长,也可以在集合声明中写默认值,再在特殊元素上覆盖:
# 集合默认给新元素 5 分钟生命周期。
nft add set inet fw_demo temp_allow {
type ipv4_addr
flags timeout
timeout 5m
}
# 这个元素使用自己的 30 秒时长,覆盖集合默认值。
nft add element inet fw_demo temp_allow { 198.51.100.24 timeout 30s }
把临时集合接到规则上,自动过期才会产生效果
集合存在并不等于它已经参与过滤。还要在链中使用集合表达式。下面的规则把集合中的地址作为来源匹配条件:
# 建立输入链,使用 accept 的默认策略便于观察演示效果。
nft add chain inet fw_demo input { type filter hook input priority 0 \; policy accept \; }
# 来源地址命中 temp_block 时丢弃;元素到期后,该地址不再命中这一条。
nft add rule inet fw_demo input ip saddr @temp_block counter drop
规则里引用的是集合名,不需要把每个地址展开成一条规则。元素在集合内时,规则可以匹配;元素自动移除后,规则仍然存在,但该地址不再满足 @temp_block。
如果需要一次性加入多个不同的临时元素,可以为每个元素设置相同或不同的时间:
# 同一批元素可以使用不同的过期时间,便于按来源设置风险窗口。
nft add element inet fw_demo temp_block {
198.51.100.25 timeout 10s,
198.51.100.26 timeout 1m
}
用 expires 判断元素还剩多久
排查“规则为什么还在匹配”或“为什么已经不匹配”时,先列出集合,而不是只看规则文本。集合输出会展示元素的 timeout 和当前 expires 值:
# 查看集合定义、元素和剩余时间。 nft list set inet fw_demo temp_block # 也可以查看整套规则,确认规则仍然引用了该集合。 nft list ruleset
示意输出可能包含下面这样的信息:
table inet fw_demo {
set temp_block {
type ipv4_addr
flags timeout
elements = { 198.51.100.23 timeout 10s expires 7s }
}
}
timeout 10s 是加入时约定的生命周期,expires 7s 是当前剩余时间。两者不要混为一谈:前者通常不会随着倒计时变成 7 秒,后者会随着时间减少,并在元素到期后不再出现在集合中。
dynamic,timeout 什么时候会刷新倒计时
普通的带超时集合适合“加入后固定等待一段时间再删除”。如果需求是“只要再次命中就延长有效期”,还要区分集合是否允许从 packet path 更新。动态集合通常需要声明 dynamic 和 timeout,并在规则中使用添加或更新集合元素的语义。
# 声明可在匹配路径中动态维护的地址集合,并设置超时能力。
nft add set inet fw_demo recent_src {
type ipv4_addr
flags dynamic,timeout
timeout 30s
}
# 命中输入流量时,把来源地址加入集合;再次命中时可按规则语义刷新生命周期。
nft add rule inet fw_demo input ip saddr update @recent_src timeout 30s counter accept
这里的重点是“刷新语义必须由动态集合和规则表达式共同提供”,不是看到 timeout 就默认会续期。普通静态 set 中的元素会按自己的计时结束;动态集合才适合做“最近出现过的来源”一类短期状态。

gc-interval 和手动删除分别解决什么问题
gc-interval 是超时集合的垃圾回收检查间隔,只有启用超时能力时才有意义。它影响过期元素被清理的检查节奏,不应该被理解成元素生命周期本身。生命周期仍然由集合默认值或元素级 timeout 决定。
# 设置默认生命周期和垃圾回收检查间隔;时间值按 nftables 语法书写。
nft add set inet fw_demo short_lived {
type ipv4_addr
flags timeout
timeout 1m
gc-interval 10s
}
# 业务决定提前撤销时,仍可显式删除元素,不必等待超时。
nft delete element inet fw_demo short_lived { 198.51.100.30 }
临时封禁撤销、临时授权取消等场景通常需要显式删除;自然到期则交给 timeout。两者可以同时存在:一个是业务事件触发的立即变更,一个是生命周期结束后的自动清理。
哪些写法容易让“自动过期”看起来失效
| 现象 | 常见原因 | 处理方式 |
|---|---|---|
| 元素添加时报不支持超时 | set 没有 flags timeout | 重建集合或按现有配置补齐超时能力 |
| 规则还在,但地址不再被拦截 | 元素已经到期移除 | 用 nft list set 查看当前元素 |
| 命中后没有续期 | 使用了普通 timeout set,未配置动态更新语义 | 区分固定过期和命中刷新两种需求 |
| 配置文件看不到 expires | expires 是运行时倒计时状态 | 查看当前集合输出,不把剩余值当成固定配置 |
| 固定白名单莫名消失 | 把永久对象放进了 timeout set | 固定对象使用普通 set,临时对象再使用 timeout |
按场景选择普通 set、timeout set 还是动态 set
可以用下面的判断快速选型:
- 固定白名单或固定端口:使用普通 set,不给元素设置 timeout。
- 临时封禁、短期放行:使用
flags timeout,给元素设置明确的生命周期。 - 最近访问、重复命中延长窗口:考虑
dynamic,timeout,同时把更新语义写进规则。 - 需要立即撤销:保留显式
delete element的运维路径,不要只等待自动过期。
最后再检查一次集合定义、元素状态和引用规则:能在集合输出中看到预期的 timeout/expires,并在规则中看到正确的 @set,临时规则的生命周期就已经闭环。
常见问题
给规则写了 timeout,为什么没有自动过期?
nftables 的这个机制作用在 set 元素上,不是给普通 rule 增加一个倒计时。应创建带 flags timeout 的集合,并在元素上设置 timeout。
timeout 和 expires 有什么区别?
timeout 是元素的生命周期设定,expires 是当前剩余时间。查看集合时看到的 expires 会变化,到期后元素会被移除。
元素过期后需要手动删规则吗?
不需要删引用集合的规则。规则仍然可以保留,只是已经过期的元素不再在集合中,因此不会再通过该集合匹配。
想让每次命中都续期,直接把 timeout 改大可以吗?
不能把固定生命周期和命中刷新混为一谈。需要根据规则语义使用动态集合更新;如果只是固定等待后删除,普通 timeout set 更简单。
-
416 收藏
-
273 收藏
-
364 收藏
-
454 收藏
-
330 收藏
-
264 收藏
-
171 收藏
-
371 收藏
-
269 收藏
-
445 收藏
-
193 收藏
-
119 收藏
-
208 收藏
-
423 收藏
-
484 收藏
-
415 收藏
-
120 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习