Linux nftables counter 如何定位规则命中
Linux nftables 里想知道“到底哪条规则命中了”,先不要盯着整条链的默认策略。给目标规则显式加上 counter,再用 nft -a list 同时查看匹配条件、packets/bytes 和 handle;如果计数仍然无法解释,才用限定范围的 nftrace 追踪一条测试流量。这样可以把“规则没有匹配”和“数据包根本没到这条链”区分开。
官方地址:https://www.netfilter.org/projects/nftables/
- counter 统计的是它在规则中所在位置之后能看到的 packets 和 bytes,位置放错会让计数范围变大。
-a显示的 handle 用于稳定指认规则;重复列出规则,比凭肉眼猜命中更可靠。- nftrace 要只匹配目标报文,并在排查结束后删除临时链,避免输出泛滥和长期跟踪。
先看规则本身:counter 统计的不是整条链
nftables 的 counter 是规则里的一个状态语句,记录 packets 和 bytes。它不会自动覆盖所有规则,必须写在需要观察的规则中,而且同一条规则里语句的位置有意义:前面的匹配条件先把数据包筛掉,后面的 counter 才只统计通过这些条件的报文;如果把 counter 放在匹配条件前面,计数范围就会扩大。
例如,下面的示例只想观察进入本机的 HTTPS 新连接。命令是排查用的示例,不代表已经在本文环境执行。
# 先明确表、链和匹配条件,再让 counter 记录目标流量
sudo nft add rule inet fw input ct state new tcp dport 443 counter accept
# 用数字化输出并显示 handle,便于后续锁定同一条规则
sudo nft -nn -a list chain inet fw input
若规则已有 accept 或 drop,不要把 counter 放到终止语句之后。终止语句已经结束当前规则路径,后面的状态语句不会按你预期工作。对于跨多条规则汇总的场景,可以声明 named counter;但定位单条规则时,先看匿名 counter 往往更直观。
用 handle 和计数把命中规则圈出来
第一次查看建议缩小范围,不要直接把整机所有表混在一起:
# 只列出目标链;-n 避免名称翻译干扰比对,-a 显示规则 handle
sudo nft -n -a list chain inet fw input
# 规则数量较多时,用 JSON 保留 family、table、chain 和 expr 字段
sudo nft -j list chain inet fw input

接着制造一小段明确属于目标条件的流量,再重复同一条 list 命令。判断重点不是某个绝对数字,而是变化位置:
| 观察结果 | 更可能的结论 |
|---|---|
| 目标规则 packets 和 bytes 都增加 | 报文匹配到该规则,handle 可作为定位证据 |
| 上游粗粒度规则增加,目标规则不变 | 已到达该链,但没有满足目标条件,或在前面被终止 |
| 整条链计数都不变 | 先检查 family、hook、接口方向和实际路径 |
| 规则显示没有 counter | 该规则没有显式计数器,不能拿它判断命中次数 |
如果用 named counter 汇总多个端口或多条规则,可单独查看它:
# named counter 的读取对象是 family、table 和 counter 名称
sudo nft list counter inet fw https_hits
计数不变时,用 nftrace 判断数据包走到哪里
counter 只告诉你某个状态点是否被经过,不能完整解释数据包之前经过了哪些链。此时可以临时建立一个优先级合适的 trace chain,并让它只给目标报文设置 meta nftrace set 1。官方 nftables wiki 建议用 nft monitor trace 读取事件;trace id 用来关联同一条报文的多个记录。
# 临时链放在目标 prerouting 链之前;条件可再收窄到目标接口或地址
sudo nft add chain inet fw trace_chain { type filter hook prerouting priority -301; policy accept; }
sudo nft add rule inet fw trace_chain tcp dport 443 meta nftrace set 1
# 在另一个会话观察 trace id、chain、rule 和 verdict
sudo nft monitor trace
# 排查结束立即删除临时链,避免继续产生跟踪事件
sudo nft delete chain inet fw trace_chain

示意性的关键行通常类似 trace id ... input rule ... counter ... (verdict accept)。它说明的是该报文在这条规则上继续到了什么 verdict,不等同于一份长期审计日志。若输出过多,优先把入口规则的匹配条件收窄;不要为了“看得全”给所有报文打开 trace。
把一次排查收束成可复查清单
最后再做一次前后比对:记录规则的 family、table、chain、handle、匹配条件和计数变化;若用 JSON 解析,则保存对应的 rule expr。确认结果后恢复正式规则,删除 trace_chain。需要清零 named counter 时要意识到 reset 会丢失当前统计;匿名 counter 的 reset 行为还存在不同版本与实现边界,生产环境不要用“清空整套 ruleset 再导回”作为随手操作,因为它可能连其他有状态对象一起影响。
- 先问方向:报文是 input、output 还是 forward?
- 再问条件:协议、端口、地址和 ct state 是否与测试流量一致?
- 最后问状态:counter 是否放在匹配条件之后、终止语句之前?
相关问题
为什么 nft list ruleset 看不到某条规则的计数?
常见原因是规则没有显式写 counter,或者查看的 family/table/chain 不是实际挂载路径。先用 nft -a list ruleset 确认对象边界。
counter 增加能证明数据包最终被放行吗?
不能。它只证明报文经过了 counter 所在状态点;后续规则仍可能 drop、reject 或跳转。要判断最终结论,用受限 nftrace 看 verdict。
什么时候应该使用 named counter?
当多个规则需要共享同一统计口径时使用 named counter;只定位一条规则时,匿名 counter 和 handle 更容易把证据绑定到具体规则。
Go ResponseWriter 写入状态码后为什么 Header 修改不生效
- 上一篇
- Go ResponseWriter 写入状态码后为什么 Header 修改不生效
- 下一篇
- IntersectionObserver 观察大量元素时如何拆分
-
- 文章 · linux | 2小时前 | 命名空间 · 容器隔离 · 挂载 · Linux教程 · Linux mount namespace bind mount mount propagation
- Linux mount namespace 绑定挂载为何对宿主不可见
- 314浏览 收藏
-
- 文章 · linux | 5小时前 |
- Linux perf record 采样频率过高时如何调整
- 324浏览 收藏
-
- 文章 · linux | 8小时前 | systemd · 日志排查 · journalctl · 运维命令 · Linux教程 · Linux journalctl --since --until --boot 启动编号 Boot ID systemd 日志
- Linux journalctl --since 和启动编号筛选如何组合
- 127浏览 收藏
-
- 文章 · linux | 17小时前 | 命令行工具 · udev · Linux设备管理 · 内核事件 · 系统排障 · Linux udevadm monitor udev 内核事件 udev 规则动作 udevadm property subsystem 过滤
- Linux udevadm monitor 如何区分内核事件和规则动作
- 498浏览 收藏
-
- 文章 · linux | 18小时前 | Linux · nmcli · NetworkManager · 自动连接 ·
- Linux nmcli 连接自动激活失败时如何查看匹配条件
- 431浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 31次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 135次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 70次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 27次使用
-
- CMMLU
- 深入了解CMMLU中文评估基准,涵盖67个学科主题,提供数据集下载、Zero-shot/Five-shot评估方法及排行榜,助力优化中文语言模型性能。
- 16次使用
-
- 详解golang执行Linuxshell命令完整场景下的使用方法
- 2023-01-07 426浏览
-
- go程序部署到linux上运行的实现方法
- 2023-01-02 387浏览
-
- Linux系统下Go语言开发环境搭建
- 2023-01-07 242浏览
-
- 使用golang获取linux上文件的访问/创建/修改时间
- 2022-12-31 238浏览
-
- 在Linux系统中安装Go语言的详细教程
- 2022-12-29 402浏览

