Linux nftables 集合如何动态维护封禁地址
来源:17golang原创
时间:2026-10-09 12:13:54 193浏览 收藏
Linux 上需要临时封禁某个来源地址时,不必每次都修改整条防火墙规则。更合适的做法是创建一个可命名、可更新的 nftables 集合,让规则只引用这个集合;封禁动作变成向集合添加元素,解除封禁则删除元素。临时事件还可以给元素设置超时时间,到期后由 nftables 自动清理。
官方资料:https://wiki.nftables.org/wiki-nftables/index.php/Sets
动态封禁的关键是“规则稳定、集合变化”:先让 input 链引用@blocked_v4,再用nft add element、nft delete element和元素级timeout管理地址。运行时状态确认无误后,再决定是否写入持久化规则文件。
- 匿名集合绑定在规则上,不能独立增删;动态场景应使用命名集合。
flags timeout允许添加带过期时间的地址,集合级timeout是默认值。- 更新后用
nft list set检查实际集合,持久化配置则要单独维护并测试加载。
先把 nftables 集合和封禁规则拆开
匿名集合通常直接写在规则里,例如把多个端口写进一条匹配表达式。它随着规则创建和删除,不能作为独立对象接受运行时更新。命名集合则有自己的名称和类型,规则可以用 @集合名 引用,集合内容也能单独添加或删除。封禁地址这类会随事件变化的数据,应优先使用后者。
| 对象 | 职责 | 动态维护方式 |
|---|---|---|
| 命名集合 | 保存 IPv4 地址及可选超时时间 | add/delete element |
| input 链规则 | 匹配源地址并执行 drop | 低频变更,保持稳定 |
| 持久化文件 | 定义重启后应恢复的策略 | 改文件后再按系统方式加载 |

创建可被规则引用的 IPv4 封禁集合
下面的示例使用 inet 表,集合只接收 IPv4 地址。集合名应简短;nftables 文档说明命名集合最长为 16 个字符。blocked_v4 还会启用超时能力,后续才能对单个地址设置过期时间。
# 建立承载网络过滤对象的表;重复执行时应由调用方先判断对象是否已存在
sudo nft add table inet edge_filter
# 创建可独立更新的 IPv4 命名集合,并允许元素携带 timeout
sudo nft 'add set inet edge_filter blocked_v4 { type ipv4_addr; flags timeout; timeout 1h; }'
# 让 input 链引用集合;规则稳定后,封禁动作只改集合元素
sudo nft 'add chain inet edge_filter input { type filter hook input priority 0; policy accept; }'
sudo nft add rule inet edge_filter input ip saddr @blocked_v4 counter drop
生产脚本不应无条件重复创建表、集合、链和规则,否则重复执行可能返回对象已存在。可以把初始化与运行时更新分成两个阶段:初始化阶段负责加载完整规则集,事件处理阶段只允许操作集合元素,并把操作者、原因和过期时间写入自己的审计日志。
用 add、delete 和 get element 动态维护地址
集合建立后,封禁一个地址只需要添加元素。解除封禁使用删除命令;查询命令则适合放在自动化任务的回执或人工复盘中。地址来自日志或接口时,先验证 IPv4/CIDR 格式,再拼接 nft 命令,不能把未经校验的字符串直接交给 shell。
# 添加一个临时封禁地址;timeout 只对已启用 timeout 的集合有效
sudo nft add element inet edge_filter blocked_v4 '{ 203.0.113.7 timeout 15m }'
# 查询单个地址是否存在,用于生成明确的更新回执
sudo nft get element inet edge_filter blocked_v4 '{ 203.0.113.7 }'
# 解除封禁;删除元素不会改变 input 链规则
sudo nft delete element inet edge_filter blocked_v4 '{ 203.0.113.7 }'
# 查看集合全量状态,确认地址和剩余超时是否符合预期
sudo nft list set inet edge_filter blocked_v4
如果自动化系统同时收到多次相同封禁事件,应把“已存在”当作可记录的幂等结果,而不是反复改写规则。删除前也要区分地址不存在和命令本身失败。这样才能在告警风暴时保持清晰的成功、忽略和失败三种结果。
临时封禁的 timeout 如何选择
timeout 1h 是集合的默认存活时间;添加元素时写 timeout 15m 可以为单个地址覆盖默认值。gc-interval 用于设置超时元素的垃圾回收检查间隔,只有启用超时能力时才有意义。短暂的爆破拦截适合元素级超时,长期黑名单则不应只依赖临时状态。
| 场景 | 建议 | 需要留意 |
|---|---|---|
| 短时异常流量 | 添加元素并设置 5–30 分钟超时 | 回源任务必须记录过期时间 |
| 重复攻击来源 | 延长元素超时或转入长期名单 | 避免自动续期掩盖误封 |
| 业务白名单误封 | 先删除元素,再确认集合查询结果 | 不要只删除持久化文件中的一行 |

把运行时状态和重启后的配置分开管理
命令行添加的集合元素属于当前规则集;服务器重启后是否恢复,取决于系统加载的 nftables 配置文件和服务方式。若封禁是临时响应,就应把事件记录到外部审计或工单系统,而不是把每个短期地址永久写入配置。若地址需要长期生效,则应更新声明式配置,先在隔离环境加载,再按系统约定启用。
排查“命令成功但流量仍然通过”时,按这份清单缩小范围:第一,确认访问流量进入的是同一个 inet edge_filter input 链;第二,用 nft list set 确认地址类型和集合元素;第三,检查规则计数器是否增长;第四,确认前置规则没有提前 accept,也没有把地址解析成另一种族类型。nftables 集合解决的是匹配数据的维护,不会替代整套链路策略设计。
常见问题
为什么直接修改匿名集合不能动态封禁?
匿名集合绑定在规则上,规则移除后集合也随之释放,不能作为独立对象更新。需要运行时增删时,应先创建命名集合,再让规则引用它。
元素 timeout 到期后还要手动 delete 吗?
正常情况下不需要,超时元素会被清理;但业务审计仍应记录原始事件和过期时间。若要立即解除封禁,仍可显式删除元素。
只改 nftables.conf 能马上解除当前封禁吗?
不一定。配置文件是持久化来源,当前内核规则集可能仍保留旧元素。解除后应直接检查当前集合,并按系统方式重新加载配置。
把封禁地址放进命名集合,规则就能保持稳定,自动化任务也只需要维护集合元素。真正上线前,再补上输入校验、幂等回执、审计记录和持久化加载测试,动态封禁才不会变成另一套难以排查的临时规则。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
220 收藏
-
227 收藏
-
180 收藏
-
331 收藏
-
386 收藏
-
261 收藏
-
233 收藏
-
179 收藏
-
文章 · linux | 21小时前 | 容器 · Linux · 容器隔离 mount namespace PID namespace linux namespace network namespace268 收藏
-
490 收藏
-
297 收藏
-
398 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习