Linux nftables 动态集合怎么设置元素过期时间
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,不会把真实公网地址写进教程。

给单个元素覆盖默认 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 场景就可能暂时没有空间接收新元素。

参数选择没有一组适合所有机器的固定答案,可以从业务窗口反推:
- 短暂去重或近期来源观察:
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 命令 | 写入系统实际加载的持久规则文件 |
| 远程加载后连接中断 | 链策略、规则顺序、管理地址是否被加入集合 | 通过控制台恢复备份,并缩小测试范围 |
最终配置清单
- 命名集合包含正确的
type。 - 动态写入场景启用
flags dynamic, timeout。 - 集合级
timeout提供合理默认寿命。 - 特殊元素在写入时用自己的
timeout覆盖默认值。 - 需要滑动窗口时使用
update刷新寿命。 - 根据峰值元素数设置
size,并用gc-interval平衡回收及时性。 - 上线前检查规则文件、保存现有规则,并准备带外恢复路径。
小结:nftables 动态集合的元素过期并不是单个参数问题,而是四个职责清晰的部件:timeout 管寿命,update 管续期,gc-interval 管回收节奏,size 管容量边界。把它们分开理解后,无论是临时封禁、近期来源观察还是短时去重,都能得到可预测、可恢复的配置。
喵次元 iOS自签入口怎么看?公开页面的平台提示与责任边界
- 上一篇
- 喵次元 iOS自签入口怎么看?公开页面的平台提示与责任边界
- 下一篇
- tapaim电竞海选活动是什么?3.0.0版本公告与参与边界说明
-
- 文章 · linux | 3小时前 | Linux · 内存管理 · Linux OOM oom_score_adj 进程回收
- Linux oom_score_adj 怎么控制进程被回收优先级
- 306浏览 收藏
-
- 文章 · linux | 7小时前 | 进程管理 · Linux cgroup v2 cgroup.freeze cgroup.events cgroup.procs 进程冻结
- Linux cgroup v2 怎么冻结并恢复一组进程
- 467浏览 收藏
-
- 文章 · linux | 9小时前 | systemd service ReadWritePaths ProtectSystem 文件系统沙箱 Linux服务加固
- systemd ProtectSystem 与 ReadWritePaths 怎么组合
- 485浏览 收藏
-
- 文章 · linux | 12小时前 | Linux · Linux systemd-journald journald.conf RateLimitIntervalSec RateLimitBurst 日志限速
- systemd-journald 日志限速丢弃怎么调整
- 208浏览 收藏
-
- 文章 · linux | 14小时前 |
- journalctl 怎么按服务某次 invocation 筛选日志
- 466浏览 收藏
-
- 文章 · linux | 16小时前 | Linux · systemd Restart RestartMode 依赖单元
- systemd RestartMode 怎么减少依赖单元连锁失败
- 239浏览 收藏
-
- 文章 · linux | 19小时前 | 定时任务 · Linux · 运维 · Cron OnCalendar Persistent systemd timer systemd-analyze calendar
- systemd timer 替代 cron 的日历表达式配置
- 364浏览 收藏
-
- 文章 · linux | 23小时前 | Linux · 内存管理 · Linux 内存限制 cgroup v2 memory.events
- cgroup v2 限制服务内存并观察回收事件
- 494浏览 收藏
-
- 文章 · linux | 2天前 | Linux · mount namespace unshare Linux挂载隔离
- mount namespace 隔离临时挂载的操作边界
- 462浏览 收藏
-
- 文章 · linux | 2天前 | Linux · 运维 · GNU tar 增量归档 listed-incremental exclude-from CACHEDIR.TAG
- tar 增量归档排除缓存目录的参数组合
- 324浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 328次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 386次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 379次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 346次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 172次使用
-
- Go HTTP 出站请求如何防 SSRF:URL 解析、内网地址拦截与重定向复核
- 2026-08-10 275浏览
-
- Go tls.ClientHelloInfo.Conn 该放在哪里:QUIC 握手连接的取值边界
- 2026-09-03 498浏览
-
- Go crypto/tls设置最低 TLS 版本的配置边界
- 2026-09-15 321浏览
-
- Mac 启动go run main.go 总是弹出警告
- 2023-01-08 273浏览
-
- Go 1.27 的 TLS 连接证书怎么取:ConnectionState.LocalCertificate 不是对端证书
- 2026-09-01 480浏览

