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

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低频变更,保持稳定
持久化文件定义重启后应恢复的策略改文件后再按系统方式加载
Linux nftables 命名集合、input 链规则与动态封禁地址之间的静态关系说明图
图1:nftables 集合与规则边界说明图,展示地址元素由命名集合承载、input 规则负责引用;这是结构说明图,不是运行截图。

创建可被规则引用的 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 封禁地址元素从输入事件到 timeout 自动回收和状态复盘的静态关系说明图
图2:动态更新关系说明图,展示封禁事件、集合元素、规则命中、超时回收和状态复盘的职责边界;这是说明图,不是运行截图。

把运行时状态和重启后的配置分开管理

命令行添加的集合元素属于当前规则集;服务器重启后是否恢复,取决于系统加载的 nftables 配置文件和服务方式。若封禁是临时响应,就应把事件记录到外部审计或工单系统,而不是把每个短期地址永久写入配置。若地址需要长期生效,则应更新声明式配置,先在隔离环境加载,再按系统约定启用。

排查“命令成功但流量仍然通过”时,按这份清单缩小范围:第一,确认访问流量进入的是同一个 inet edge_filter input 链;第二,用 nft list set 确认地址类型和集合元素;第三,检查规则计数器是否增长;第四,确认前置规则没有提前 accept,也没有把地址解析成另一种族类型。nftables 集合解决的是匹配数据的维护,不会替代整套链路策略设计。

常见问题

为什么直接修改匿名集合不能动态封禁?

匿名集合绑定在规则上,规则移除后集合也随之释放,不能作为独立对象更新。需要运行时增删时,应先创建命名集合,再让规则引用它。

元素 timeout 到期后还要手动 delete 吗?

正常情况下不需要,超时元素会被清理;但业务审计仍应记录原始事件和过期时间。若要立即解除封禁,仍可显式删除元素。

只改 nftables.conf 能马上解除当前封禁吗?

不一定。配置文件是持久化来源,当前内核规则集可能仍保留旧元素。解除后应直接检查当前集合,并按系统方式重新加载配置。

把封禁地址放进命名集合,规则就能保持稳定,自动化任务也只需要维护集合元素。真正上线前,再补上输入校验、幂等回执、审计记录和持久化加载测试,动态封禁才不会变成另一套难以排查的临时规则。

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