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

nftables set 怎么为元素设置超时时间

来源:17golang原创

时间:2026-09-28 06:20:51 277浏览 收藏

如果 nftables 的黑名单、临时放行名单或限流集合只需要保留一段时间,不必另外写定时任务删除元素。给命名 set 开启 timeout 能力后,可以在添加元素时写入自己的寿命;用 nft list set 查看时,expires 会显示剩余倒计时,归零后元素自动消失。

官方地址:https://wiki.nftables.org/wiki-nftables/index.php/Element_timeouts

要点速览
  • 命名 set 先声明 flags timeout,元素才能携带独立的超时时间。
  • timeout 是元素寿命,expires 是当前倒计时;需要重新设定时应删除后重建。
  • 管理面重复 add 不等于续期,按数据包刷新要使用带 dynamic 的 set 和 update。

一、先区分 timeout、expires 与 set 的能力

nftables 的 set 是规则引用的集合,元素可以是 IPv4 地址、端口或其他支持的数据类型。超时不是普通元素的默认属性,而是 set 声明的一种能力。最容易混淆的是两个时间字段:timeout 表示从写入开始计算的寿命,expires 表示当前还剩多少时间。

因此,看到下面这种列表结果时,不要把 expires 8s 当成永久配置。它只是当前状态;元素被删除再添加后,倒计时会按新的 timeout 重新开始。

elements = { 192.0.2.10 timeout 10m expires 8m }
nftables 命名 set 使用 flags timeout 管理 IPv4 元素寿命和 expires 倒计时的结构说明图
图1:nftables set 元素超时关系说明图,展示 flags timeout、timeout 与 expires 的边界,不是运行截图。

二、创建支持超时的命名 set

先创建一个 inet 表和命名 set,再添加带寿命的地址。命令中的分号需要放在单引号里交给 nft 解析;如果直接在 shell 中展开,分号会被 shell 当成命令分隔符。

# 创建演示表;实际环境请先确认名称不会覆盖现有规则
nft add table inet ttl_demo

# 开启 timeout 能力;命名 set 才能接收带寿命的元素
nft 'add set inet ttl_demo denylist { type ipv4_addr; flags timeout; }'

# 给这个地址设置十分钟寿命;过期后元素会被 nftables 清理
nft 'add element inet ttl_demo denylist { 192.0.2.10 timeout 10m }'

# 查看当前元素和剩余倒计时;这是静态检查命令,不代表固定输出
nft list set inet ttl_demo denylist

如果要让不同地址使用不同寿命,可以在同一条添加命令中分别写 timeout 30s、timeout 2h。这里使用文档保留的 192.0.2.0/24 示例地址,生产配置应换成自己的实际地址并评估误封风险。

三、按元素设置不同的过期时间

元素的超时参数跟在元素值后面,而不是写进规则匹配表达式。常见的检查组合如下:

对象作用排查重点
flags timeout让命名 set 支持超时元素创建 set 时声明
timeout 10m设置元素寿命单位可用 s、m、h 等组合
expires显示当前剩余时间通过 list set 查看
delete + add重新设定寿命不能只依赖重复添加

元素已经存在时,直接再次指定 timeout 或 expires 不能修改这两个值。需要重置时,先删除该元素,再按新的时间重新添加:

# 先删除旧元素,避免把旧的 expires 当成可修改字段
nft 'delete element inet ttl_demo denylist { 192.0.2.10 }'

# 重新添加并设置新的寿命;错误返回时不要继续假设元素已更新
nft 'add element inet ttl_demo denylist { 192.0.2.10 timeout 30m }'

# 再读取集合,确认元素已重新出现并获得新的倒计时
nft list set inet ttl_demo denylist

四、需要续期时改用 update

如果需求是“地址每次命中都延长封禁窗口”,管理面反复执行 add 不是合适方案。nftables 文档区分了两种行为:add 添加元素时不会刷新已有元素的超时,数据包路径上的 update 才会把倒计时重新设为指定值。

这个模式适合临时黑名单、简单的访问频率记忆等场景。若只是后台脚本偶尔加入一个地址,不需要数据包路径续期,使用前面的命名 set 加元素超时即可,避免把 dynamic 更新逻辑引入不必要的规则链。

nftables add 与 update 对 timed set 元素是否刷新 expires 倒计时的边界结构图
图2:add 与 update 的超时刷新边界结构图,说明规则关系,不是命令执行证据。

五、用检查清单排查超时不生效

  1. 先看 set 声明:确认是命名 set,并且包含 flags timeout;匿名 set 不能按这种方式动态维护。
  2. 再看元素语法:确认 timeout 写在元素值之后,时间单位没有拼错。
  3. 检查查看方式:使用 nft list set family table set,不要只看规则引用是否存在。
  4. 区分续期模型:重复 add 不代表刷新;要按包续期时检查 dynamic 和 update。
  5. 检查权限和版本:命令失败时保留 nft 的原始错误,确认当前用户权限、nft 命令版本与内核支持一致,不要只凭 shell 返回状态判断。

相关问题

timeout 和 expires 可以互换吗?

不能。timeout 是设定的寿命,expires 是运行中的倒计时;后者随时间变化,不能当成新的配置值。

元素过期后还会匹配规则吗?

元素被集合清理后就不再参与该 set 的匹配。要保留它,应在过期前重新添加,或使用 update 让数据包命中时刷新。

为什么重复 add 没有延长封禁时间?

固定的管理面 add 不负责刷新已有元素的 timeout。按包自动续期时,应设计 dynamic set,并使用 update 表达刷新语义。

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