当前位置:首页 > 文章列表 > 文章 > linux > Linux nftables 动态集合怎么设置元素过期时间

Linux nftables 动态集合怎么设置元素过期时间

来源:17golang原创 2026-10-04 19:56:25 0浏览 收藏

Linux nftables 动态集合设置元素过期时间,最小答案是:在命名集合中启用 dynamic 和 timeout 标志,再用集合级 timeout 给元素设置默认寿命。某个地址需要不同寿命时,在添加元素时附加自己的 timeout;如果希望地址每次再次命中都重新开始倒计时,则在规则里使用 update。

先记住三个结论
  • 集合级 timeout 10m 是默认值,元素级 timeout 2m 可以覆盖它。
  • expires 是当前剩余寿命,适合观察和复制状态,不是平时设置默认值的入口。
  • gc-interval 决定回收扫描节奏,不会延长元素的逻辑有效期。

主要文档:https://netfilter.org/projects/nftables/manpage.html;集合参考:https://wiki.nftables.org/wiki-nftables/index.php/Sets。

先做一个带 10 分钟默认寿命的动态集合

下面用独立的 inet demo_guard 表演示。输入链保持 policy accept,只丢弃已经明确放进集合的文档示例地址,避免把“怎样设置过期时间”混成一套激进的主机防火墙。生产机器上不要直接照搬表名覆盖现有配置,应把 set 和引用规则合并到自己的规则文件。

# 这是独立演示规则;生产环境请合并到现有规则集。
table inet demo_guard {
    set temp_block_v4 {
        type ipv4_addr
        flags dynamic, timeout
        timeout 10m        # 未单独指定时,元素默认存活 10 分钟。
        gc-interval 30s    # 每 30 秒安排一次过期元素回收扫描。
        size 65536         # 限制集合容量,避免动态增长失去边界。
    }

    chain input {
        type filter hook input priority filter; policy accept;
        # 只匹配已经进入临时封禁集合的源地址。
        ip saddr @temp_block_v4 counter drop
    }
}

这里缺一项都可能让行为和预期不同:dynamic 允许从数据包路径动态更新集合;timeout 允许元素自动到期;集合级 timeout 10m 给没有单独声明寿命的元素提供默认值;size 给动态集合一个明确上限。官方手册还特别说明,从数据包路径向集合添加元素时应定义最大容量,添加动作也需要有超时边界。

先把规则保存为 /etc/nftables.d/demo-guard.nft,然后分两步检查和加载:

# 只检查规则文件语法与可解析性,不修改当前规则集。
sudo nft -c -f /etc/nftables.d/demo-guard.nft

# 确认仍有控制台或带外访问后,再加载这份独立演示规则。
sudo nft -f /etc/nftables.d/demo-guard.nft

# 查看集合定义,确认 flags、timeout、gc-interval 和 size 已生效。
sudo nft list set inet demo_guard temp_block_v4

如果主机正在远程维护,加载任何网络规则前都要保存当前规则集并预留恢复通道。本文示例使用文档专用地址段 192.0.2.0/24、198.51.100.0/24 和 203.0.113.0/24,不会把真实公网地址写进教程。

nftables 动态集合的类型、标志、默认超时、回收间隔、容量与元素寿命静态关系图
图1:动态集合的五个核心属性各管一件事;元素从默认 timeout 获得寿命,也可以在写入时覆盖该值。这是静态关系图。

给单个元素覆盖默认 timeout

集合默认是 10 分钟,并不妨碍某个元素只保留 2 分钟,另一个元素保留 1 小时。元素级 timeout 优先于集合默认值:

# 使用集合默认值,这个元素默认存活 10 分钟。
sudo nft add element inet demo_guard temp_block_v4 '{ 192.0.2.10 }'

# 覆盖默认值,这个元素只存活 2 分钟。
sudo nft add element inet demo_guard temp_block_v4 '{ 198.51.100.8 timeout 2m }'

# 为另一个元素指定 1 小时寿命。
sudo nft add element inet demo_guard temp_block_v4 '{ 203.0.113.20 timeout 1h }'

# 查看当前元素及其剩余 expires 时间。
sudo nft list set inet demo_guard temp_block_v4

输出中的 timeout 表示该元素被赋予的寿命,expires 表示此刻还剩多少时间。随着时间流逝,expires 会减少。手册把 expires 定义为剩余到期时间,它更适合做规则集状态复制或运维观察;日常配置元素寿命时仍应使用 timeout。

需要提前移除元素时,不必等待超时:

# 提前删除一个临时封禁元素,不影响集合中的其他地址。
sudo nft delete element inet demo_guard temp_block_v4 '{ 198.51.100.8 }'

# 再次列出集合,确认目标元素已经移除。
sudo nft list set inet demo_guard temp_block_v4

add 和 update 的差别在于是否刷新寿命

动态集合最常见的需求不是“固定两分钟后删除”,而是“只要一分钟内持续出现新连接,就继续把该地址视为活跃”。这时应使用 update。它会在元素已存在时刷新超时;add 更适合首次插入,不应拿它代替滑动窗口。

为了避免示例直接改变放行策略,下面创建一个只记录最近 SSH SYN 来源的观察集合。它不会丢弃流量:

# 这张表只演示动态观察,不包含 drop 或 reject 动作。
table inet demo_observe {
    set recent_ssh_v4 {
        type ipv4_addr
        flags dynamic, timeout
        timeout 1m         # 默认观察窗口是一分钟。
        gc-interval 15s    # 较短回收周期便于及时释放容量。
        size 32768         # 数据包路径更新必须有明确容量边界。
    }

    chain input {
        type filter hook input priority filter; policy accept;
        # 每次收到 SSH SYN 都写入或刷新源地址的一分钟寿命。
        tcp flags syn tcp dport 22 update @recent_ssh_v4 { ip saddr timeout 1m } counter
    }
}

同一个源地址在 40 秒后再次发送 SYN,update 会让它重新获得一分钟寿命;如果随后完全不再命中,它才会到期。这个行为就是滑动窗口。若改成 add,应把它理解为“缺少时加入”,而不是“每次访问都续期”。

观察效果时可以间隔几秒执行:

# 列出观察集合,关注每个元素不断变化的 expires 值。
sudo nft list set inet demo_observe recent_ssh_v4

# 以监视模式观察 nftables 对象变化;结束时按 Ctrl+C。
sudo nft monitor

将观察集合进一步用于限速、隔离或封禁属于另一个策略层问题。更稳妥的做法是先确认采集条件不会把堡垒机、反向代理或 NAT 出口误认为单一恶意来源,再增加动作规则。

gc-interval 不等于 timeout

timeout 决定元素何时不再有效,gc-interval 决定内核多久安排一次垃圾回收。两者是逻辑到期和资源回收两个阶段,不能互相替代。

例如元素寿命为 60 秒、回收间隔为 30 秒。元素在第 60 秒到期后不应再作为有效匹配项,但它占用的内部槽位可能要等到后续垃圾回收才彻底释放。官方手册提醒:已经超时但尚未被回收的元素仍可能计入集合大小。若 gc-interval 设得过大,而 size 又很小,高 churn 场景就可能暂时没有空间接收新元素。

nftables 元素从有效倒计时、逻辑到期到垃圾回收释放容量的静态状态关系图
图2:timeout 决定逻辑有效期,gc-interval 决定到期对象何时被扫描回收;两者共同影响高频动态集合的容量表现。这是静态状态图。

参数选择没有一组适合所有机器的固定答案,可以从业务窗口反推:

  • 短暂去重或近期来源观察:timeout 常常只需几十秒到几分钟,回收间隔也可以较短。
  • 临时阻断:寿命通常更长,但必须保留人工删除入口,不能只依赖自然到期。
  • 来源数量波动很大:优先估算峰值唯一地址数,再给 size 留余量,并监控集合是否接近上限。
  • CPU 更敏感:不要为了“立即清理”把回收周期压得过短,应在回收及时性与扫描开销之间折中。

把静态地址和临时地址分开更好维护

实践中我更倾向于把长期策略与自动过期状态放在两个集合。长期拒绝名单不设置超时,临时集合启用 timeout;规则可以同时引用两者。这样审计时一眼就能分清“管理员明确配置”与“运行中动态产生”,备份和恢复也更简单。

# 长期集合不声明 timeout,内容由配置管理维护。
set permanent_block_v4 {
    type ipv4_addr
    elements = { 192.0.2.10 }
}

# 临时集合启用自动过期,内容可以由受控自动化写入。
set temporary_block_v4 {
    type ipv4_addr
    flags dynamic, timeout
    timeout 15m        # 临时元素默认保留 15 分钟。
    gc-interval 30s    # 定期释放已到期元素占用的容量。
    size 65536         # 限制最坏情况下的元素数量。
}

不要把 nftables set 的元素超时与 conntrack 超时混为一谈。前者管理集合成员,后者管理连接跟踪状态;即使源地址从 set 中到期,既有连接是否继续、后续数据包如何处理,仍取决于完整规则顺序和连接状态匹配。

上线前的安全检查与回退

防火墙调整最危险的不是语法错误,而是语法正确却把管理入口一起挡掉。尤其通过 SSH 操作远程主机时,应保留控制台或带外访问,并保存当前规则:

# 保存当前完整规则集,文件权限应只允许管理员读取。
sudo nft list ruleset > /root/nftables-before-timeout.nft

# 检查待加载文件;通过后仍要人工确认表名、链优先级和策略。
sudo nft -c -f /etc/nftables.d/demo-guard.nft

# 如果新规则造成异常,可从已保存文件恢复原规则集。
sudo nft -f /root/nftables-before-timeout.nft

如果系统由发行版服务、配置管理平台、容器编排器或防火墙前端维护,不要绕开它直接写临时命令。应把 set 定义放进权威配置源,并确认重启后规则仍会恢复。直接命令适合实验和排查,不等于持久化。

常见问题对照

现象优先检查处理方向
元素一直不消失集合是否声明 timeout 标志,元素是否实际带有寿命补齐 flags 与默认 timeout,重新添加元素
重复命中却没有续期规则使用的是 add 还是 update滑动窗口使用 update,并显式给出 timeout
集合看似到期却仍很快满size 是否过小,gc-interval 是否过长估算峰值唯一元素数,并调整回收节奏
命令重启后失效是否只执行了即时 nft 命令写入系统实际加载的持久规则文件
远程加载后连接中断链策略、规则顺序、管理地址是否被加入集合通过控制台恢复备份,并缩小测试范围

最终配置清单

  1. 命名集合包含正确的 type。
  2. 动态写入场景启用 flags dynamic, timeout。
  3. 集合级 timeout 提供合理默认寿命。
  4. 特殊元素在写入时用自己的 timeout 覆盖默认值。
  5. 需要滑动窗口时使用 update 刷新寿命。
  6. 根据峰值元素数设置 size,并用 gc-interval 平衡回收及时性。
  7. 上线前检查规则文件、保存现有规则,并准备带外恢复路径。

小结:nftables 动态集合的元素过期并不是单个参数问题,而是四个职责清晰的部件:timeout 管寿命,update 管续期,gc-interval 管回收节奏,size 管容量边界。把它们分开理解后,无论是临时封禁、近期来源观察还是短时去重,都能得到可预测、可恢复的配置。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
喵次元 iOS自签入口怎么看?公开页面的平台提示与责任边界喵次元 iOS自签入口怎么看?公开页面的平台提示与责任边界
上一篇
喵次元 iOS自签入口怎么看?公开页面的平台提示与责任边界
tapaim电竞海选活动是什么?3.0.0版本公告与参与边界说明
下一篇
tapaim电竞海选活动是什么?3.0.0版本公告与参与边界说明
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    328次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    386次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    379次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    346次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    172次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码