基于 eBPF 的网络全链路排查工具,支持 AI 诊断闭环分析
在实际网络排查中,我们经常遇到以下问题:
-
安全进程 EDR 在内核中拦截网络:传统的网络抓包工具(如 tcpdump)无法捕获内核层面的网络拦截行为,导致无法定位数据包在哪个环节被丢弃。
-
全链路跟踪困难:tcpdump 基于 TC(Traffic Control)模块实现抓包,只能捕获网络接口层面的数据包,无法跟踪数据包在内核网络栈中的完整路径。
-
本地防火墙链路不可见:无法抓取 Netfilter 框架中的处理流程,包括防火墙规则、NAT 转换等关键环节。
-
进程关联困难:无法直接关联网络流量与用户进程,难以定位是哪个进程产生的流量。
-
抓包结果解读成本高:即使拿到了完整链路和异常样本,排障人员仍需要手工梳理统计信息、异常模式和可能根因,分析效率依赖经验。
| 特性 | NetBee | tcpdump |
|---|---|---|
| 抓包方式 | eBPF kprobe/kretprobe | TC 模块 |
| 网络栈覆盖 | 全链路(从网卡到应用层) | 仅网络接口层 |
| 内核拦截可见 | ✅ 可捕获内核拦截点 | ❌ 不可见 |
| Netfilter 跟踪 | ✅ 支持(PRE_ROUTING、LOCAL_IN、FORWARD、LOCAL_OUT、POST_ROUTING) | ❌ 不支持 |
| 输出格式 | ✅ 可视化表格,无需 Wireshark | ❌ 需要 Wireshark 分析 |
| 调用栈跟踪 | ✅ 支持(kfree_skb 调用栈) | ❌ 不支持 |
| 实时过滤 | ✅ 内核层过滤,性能高 | ✅ 支持 |
-
全链路网络跟踪
- 跟踪数据包从网卡接收(
netif_rx)到应用层处理(tcp_v4_rcv、udp_rcv)的完整路径 - 支持 Netfilter 五个钩子点的跟踪(PRE_ROUTING、LOCAL_IN、FORWARD、LOCAL_OUT、POST_ROUTING)
- 显示数据包经过的内核函数链
- 跟踪数据包从网卡接收(
-
可视化输出
- 表格化输出,无需借助 Wireshark 分析
- 颜色标记:RST 标志显示红色,TCP 重传显示红色,NF DROP 显示红色
- 自动合并相同 packet ID 的数据包,显示完整路径
-
进程信息抓取
- 自动关联网络流量与用户进程(PID、进程名)
- 支持调用栈跟踪(
-kfree参数)
-
TCP 重传检测
- 基于 Seq 和 Ack 自动识别 TCP 重传
- 重传包显示
[TCP Retransmission]标记,Seq 和 Ack 显示红色
-
灵活的过滤功能
- 协议过滤(TCP、UDP、ICMP)
- 主机过滤(源 IP、目标 IP、任意 IP)
- 端口过滤(源端口、目标端口、任意端口)
- 内核层过滤,性能高
-
Netfilter 信息
- 显示数据包经过的 Netfilter 钩子点
- 显示处理结果(ACCEPT、DROP、OTHER)
- DROP 结果自动标记为红色
-
AI 诊断报告
- 使用
-AI在抓包结束后自动调用云端 AI 进行诊断 - 自动生成抓包摘要、上传完整抓包文本,并输出本地 Markdown/TXT 报告
- 控制台打印诊断摘要、抓包文件下载链接和详细报告路径,便于快速分享与复盘
- 保存
conversation_id,支持基于历史诊断结果继续追问和多轮分析
- 使用
NetBee 不只是“抓到包”,更强调“把抓到的链路信息转成可执行结论”。AI 在整个排障流程中的作用主要体现在:
-
把原始抓包转成诊断结论
- 自动归纳抓包概况、协议分布、DROP/RST/重传等关键统计
- 从大量链路明细中提炼综合结论、已知异常、最可能根因和建议动作
-
降低排障门槛
- 一线同学无需手工阅读长篇抓包文本,也能快速获得可读结论
- 将“看懂内核链路”转化为“先读诊断摘要,再看详细报告”
-
形成排障闭环
- 抓包结束即可自动出报告,无需再手工整理材料
- 控制台、抓包下载链接、本地诊断报告三者联动,方便团队协作和问题复盘
-
支持连续追问
- 保存 AI 返回的
conversation_id - 后续通过
-keep基于上次会话继续分析,适合二次排查、补充抓包、验证修复效果
- 保存 AI 返回的
┌─────────────────────────────────────────────────────────────┐
│ 用户空间 (Go) │
├─────────────────────────────────────────────────────────────┤
│ cmd/main.go - 主程序入口 │
│ ├─ 参数解析与配置管理 │
│ ├─ eBPF 程序加载与链接 │
│ ├─ Ring Buffer 事件处理 │
│ └─ AI 诊断触发与报告落盘 │
├─────────────────────────────────────────────────────────────┤
│ pkg/core/ - 核心功能模块 │
│ ├─ event.go - 事件结构定义与格式化 │
│ ├─ filter.go - 过滤配置解析 │
│ ├─ packet_merger.go - 数据包合并与格式化 │
│ ├─ retransmission_ - TCP 重传检测 │
│ │ detector.go │
│ ├─ netfilter.go - Netfilter 信息格式化 │
│ ├─ symbol_resolver.go - 符号解析(调用栈) │
│ └─ protocol.go - 协议相关工具函数 │
├─────────────────────────────────────────────────────────────┤
│ pkg/comm/color/ - 颜色输出模块 │
│ ├─ manager.go - 颜色管理器 │
│ ├─ formatter.go - 格式化器 │
│ └─ rules.go - 颜色规则 │
├─────────────────────────────────────────────────────────────┤
│ pkg/diagnose/ - AI 诊断模块 │
│ ├─ capture.go - 抓包文本缓存与持久化 │
│ ├─ summary.go - 统计摘要提取 │
│ ├─ client.go - 云端 AI 接口调用与文件上传 │
│ └─ report.go - 诊断报告/会话 ID 落盘 │
└─────────────────────────────────────────────────────────────┘
↕ Ring Buffer
┌─────────────────────────────────────────────────────────────┐
│ 内核空间 (eBPF) │
├─────────────────────────────────────────────────────────────┤
│ ebpf/netbee.ebpf.c - eBPF 程序 │
│ ├─ kprobe 钩子点 │
│ │ ├─ netif_rx - 网卡接收 │
│ │ ├─ ip_rcv - IP 层接收 │
│ │ ├─ ip_local_deliver - 本地交付 │
│ │ ├─ tcp_v4_rcv - TCP 接收 │
│ │ ├─ udp_rcv - UDP 接收 │
│ │ ├─ dev_queue_xmit - 设备发送 │
│ │ └─ kfree_skb - 数据包释放 │
│ ├─ kretprobe 钩子点 │
│ │ └─ nf_hook_slow - Netfilter 处理结果 │
│ ├─ 数据包解析 │
│ │ ├─ 以太网头解析(MAC 地址) │
│ │ ├─ IP 头解析(IP 地址、TTL) │
│ │ └─ TCP/UDP 头解析(端口、Seq、Ack) │
│ └─ 过滤与事件提交 │
│ ├─ 内核层过滤(协议、IP、端口) │
│ └─ Ring Buffer 事件提交 │
└─────────────────────────────────────────────────────────────┘
↕ HTTP / 文件上传
┌─────────────────────────────────────────────────────────────┐
│ 云端 AI 与临时文件服务 │
├─────────────────────────────────────────────────────────────┤
│ 文件临时上传服务 - 保存完整抓包文本并返回下载链接 │
│ Dify Chat API - 基于摘要 + 原始抓包进行阻塞式诊断 │
│ 会话上下文 - 通过 conversation_id 保持多轮连续分析 │
└─────────────────────────────────────────────────────────────┘
AI 诊断被设计成 NetBee 的后处理分析链路,而不是独立外挂脚本。其设计目标是:在不影响原始抓包能力的前提下,把原始事件流自动转成一份可交付、可追问、可复盘的诊断结果。
核心设计点如下:
-
采集与展示解耦
- 抓包明细可以不在控制台实时刷出,但原始文本仍会完整缓存
- 这样既避免大流量场景下终端刷屏,也保证 AI 诊断使用的是完整抓包内容
-
摘要 + 全量原文双轨输入
- 本地先提取抓包大小、协议分布、DROP/RST/重传次数、关键异常样本等摘要
- 同时上传完整抓包原文,让 AI 既能快速理解全局,也能回看细节
-
阻塞式诊断输出
- 抓包结束后同步等待 AI 返回结果
- 保证控制台提示、抓包链接、诊断报告三者在一次执行中闭环产出
-
报告与会话状态落盘
- AI 结果会落成本地报告文件
conversation_id会额外保存到与报告同目录的固定文件中,便于后续续聊
-
支持连续排障
- 使用
-keep时,会自动读取上次保存的conversation_id - 在真正续聊前,会先调用
/messages对该conversation_id做服务端预检 - 只有预检通过时才沿用历史会话;若会话不存在或无效,则自动退化为首次诊断
- 适合“第一次抓包得到初判 -> 第二次补抓后继续追问 -> 第三次验证修复效果”的连续分析流程
- 使用
NetBee 的 AI 提示词不是简单的一句“帮我分析抓包”,而是围绕“稳定输出、强制看原文、支持连续问答”三个目标设计的。
首次诊断对应普通 -AI 模式,设计目标是让 AI 在第一次看到抓包时,快速完成“从原始抓包到诊断结论”的首轮归纳。
设计重点:
- 先定输出结构:强制 AI 使用固定 Markdown 章节,保证控制台摘要提取和报告展示稳定
- 强调原文优先:明确要求 AI 必须分析上传的抓包文件原文,不能只复述本地摘要
- 证据驱动结论:要求 AI 在“关键证据”“综合判断”中体现抓包中的协议分布、报文方向、重传、DROP、RST、函数链路、进程信息等证据
- 不确定就明确说:如果抓包证据不足,必须输出“证据不足”或“仍需进一步验证”,避免把猜测当作结论
- 从首诊角度组织内容:更关注“整个链路发生了什么”“最可能根因是什么”“建议先做什么排查”
-keep 模式不是重新起一个全新问题,而是基于历史会话继续追问同一个网络问题,因此提示词设计重点从“首诊归纳”转为“增量分析”。
设计重点:
- 基于历史上下文继续分析:明确告诉 AI 当前不是首次诊断,而是基于之前的
conversation_id延续分析 - 本次抓包优先级最高:即使历史结论已经存在,只要本次上传的抓包原文和历史判断冲突,也必须以本次抓包原文为准
- 必须说明变化关系:强制 AI 明确说明本次相较上次是“延续”“修正”还是“推翻”
- 突出增量价值:关注“本次新增了什么现象”“相比上一轮结论哪里更确定、哪里被修正”
- 适合多轮排障闭环:第一次用于初判,第二次用于补证据,第三次可用于验证修复效果
AI 诊断并不是只靠一段提示词完成,而是三类输入一起工作:
-
提示词(Query)
- 告诉 AI 角色、输出格式、判断规则和硬约束
- 决定 AI 输出是否稳定、是否聚焦网络排障、是否优先看原文
-
会话上下文(
conversation_id)- 只在
-keep时参与 - 让 AI 能继承上一轮结论、追问记录和判断路径
- 用于回答“这次和上次相比发生了什么变化”
- 在使用前会先通过
/messages做一次合法性校验,避免把失效会话直接传给 AI
- 只在
-
本次抓包输入
- 包括本地提取的摘要,以及上传的完整抓包文件原文
- 摘要用于快速告诉 AI 关键统计信息
- 抓包文件原文用于真正支撑证据和结论
三者分工如下:
- 提示词负责“规定怎么答”
- 历史会话负责“继承之前答过什么”
- 抓包原文负责“决定这次到底看到了什么证据”
因此,NetBee 的设计原则是:
- 摘要只是导航,不是最终依据
- 历史结论只是背景,不是绝对真相
- 本次抓包原文才是最终判断依据
下面是当前代码中实际使用的两套提示词模板。
你是一名资深网络排障工程师,请根据 netbee 抓包结果分析问题。
硬约束:
1. 你必须结合本次请求附带的抓包文件原文进行分析,不能只依据摘要下结论。
2. 如果摘要信息与抓包文件原文不一致,必须以抓包文件原文为准。
3. 你的结论中必须引用抓包文件原文里能够支撑判断的现象,例如协议分布、报文方向、TCP 标志、重传、RST、DROP、函数链路、进程信息、时间顺序等。
4. 如果抓包文件原文不足以支撑某个结论,必须明确写“证据不足”或“仍需进一步抓包验证”,不能把猜测写成确定结论。
5. 不允许脱离抓包文件内容泛泛而谈,不允许只重复摘要,不允许输出与抓包证据无关的模板化建议。
6. 你输出的“关键证据”和“综合判断”必须体现你确实分析了抓包文件原文,而不是只重述摘要。
7. 如果本次请求中同时提供了摘要和抓包文件原文,摘要仅用于帮助你快速定位重点,最终判断必须以抓包文件原文为依据。
你必须严格按下面的 Markdown 模板输出,标题名称、标题层级、分隔线都不要改,不能缺少任何章节,不能输出模板之外的额外前言、后记或客套话。
固定格式要求:
1. 必须包含且仅按以下顺序输出这些一级/二级标题:
- ## 0. 整个网络链路过程:问题出在哪个环节
- ## 1. 现象总结
- ## 2. 最可能的根因(按概率排序)
- ## 3. 关键证据
- ## 4. 建议的排查步骤
- ## 5. 风险与影响判断
- # 结论
- ## 综合判断
2. 在 # 结论 之前必须单独输出一行 ---
3. 在 ## 综合判断 章节末尾必须再单独输出一行 ---
4. # 结论 下必须先写 ## 综合判断
5. ## 综合判断 下必须包含两个固定三级标题:
- ### 已知异常
- ### 最可能根因
6. ### 最可能根因 下必须输出编号列表 1. 2. 3. 4.
7. 不要把“综合判断”写成“综合结论”或其他近义词,必须严格使用 ## 综合判断
8. 不要使用代码块包裹全文
请直接按下面模板产出内容:
## 0. 整个网络链路过程:问题出在哪个环节
[正文]
## 1. 现象总结
[正文]
## 2. 最可能的根因(按概率排序)
[正文]
## 3. 关键证据
[正文]
## 4. 建议的排查步骤
[正文]
## 5. 风险与影响判断
[正文]
---
# 结论
## 综合判断
[先给 1-2 句总判断]
### 已知异常
- [异常1]
- [异常2]
- [异常3]
### 最可能根因
1. [根因1]
2. [根因2]
3. [根因3]
4. [根因4]
---
以下是本次抓包的本地摘要:
[summary]
你是一名资深网络排障工程师,当前不是首次分析,而是基于之前会话继续诊断同一个网络问题。
硬约束:
1. 你必须结合当前会话中的历史结论,以及本次请求附带的抓包文件原文共同分析,不能只依据历史结论或本地摘要下结论。
2. 如果历史结论、本地摘要与本次抓包文件原文不一致,必须优先以本次抓包文件原文为准,并明确指出哪些旧结论需要修正。
3. 你必须明确说明:本次结论相较于上次是“延续”“修正”还是“推翻”,不能省略。
4. 你的结论中必须引用本次抓包文件原文里能够支撑判断的现象,例如协议分布、报文方向、TCP 标志、重传、RST、DROP、函数链路、进程信息、时间顺序等。
5. 如果本次抓包文件原文不足以推翻或确认上次判断,必须明确写“证据不足”或“仍需进一步验证”,不能把猜测写成确定结论。
6. 不允许脱离本次抓包文件内容泛泛而谈,不允许只重复历史结论,不允许只重述摘要。
7. “关键证据”“与上次相比”“综合判断”这三部分必须体现你确实分析了本次上传的抓包文件原文。
你必须严格按下面的 Markdown 模板输出,标题名称、标题层级、分隔线都不要改,不能缺少任何章节,不能输出模板之外的额外前言、后记或客套话。
固定格式要求:
1. 必须包含且仅按以下顺序输出这些一级/二级标题:
- ## 0. 历史结论与本次变化
- ## 1. 本次抓包的新增现象
- ## 2. 与上一轮判断相比的变化
- ## 3. 当前最可能的根因(按概率排序)
- ## 4. 关键证据
- ## 5. 建议的下一步排查
- ## 6. 风险与影响判断
- # 结论
- ## 综合判断
2. 在 # 结论 之前必须单独输出一行 ---
3. 在 ## 综合判断 章节末尾必须再单独输出一行 ---
4. # 结论 下必须先写 ## 综合判断
5. ## 综合判断 下必须包含三个固定三级标题:
- ### 与上次相比
- ### 已知异常
- ### 最可能根因
6. ### 最可能根因 下必须输出编号列表 1. 2. 3. 4.
7. 不要把“综合判断”写成“综合结论”或其他近义词,必须严格使用 ## 综合判断
8. 不要使用代码块包裹全文
9. 如果历史会话中已有结论,本次必须显式说明“延续/修正/推翻”中的哪一种,不能省略
10. 如果本次抓包不足以推翻上一轮结论,优先输出“延续并增强证据”,不要轻易完全改判
请直接按下面模板产出内容:
## 0. 历史结论与本次变化
[先简要概述上一轮主要结论,再说明本次新增抓包相对上次的主要变化]
## 1. 本次抓包的新增现象
[正文]
## 2. 与上一轮判断相比的变化
[明确写出哪些判断被延续、哪些被修正、哪些被推翻]
## 3. 当前最可能的根因(按概率排序)
[正文]
## 4. 关键证据
[正文]
## 5. 建议的下一步排查
[正文]
## 6. 风险与影响判断
[正文]
---
# 结论
## 综合判断
[先给 1-2 句总判断,必须体现这是一次续查,而不是首次分析]
### 与上次相比
- [延续点1]
- [修正点1]
- [仍待确认点1]
### 已知异常
- [异常1]
- [异常2]
- [异常3]
### 最可能根因
1. [根因1]
2. [根因2]
3. [根因3]
4. [根因4]
---
以下是本次抓包的本地摘要:
[summary]
位置: ebpf/netbee.ebpf.c
职责:
- 在内核关键网络函数处插入探针(kprobe/kretprobe)
- 解析网络数据包(以太网、IP、TCP/UDP)
- 执行内核层过滤(减少用户空间开销)
- 通过 Ring Buffer 将事件发送到用户空间
关键函数:
do_trace_skb(): 核心的数据包解析和事件生成函数apply_filters(): 内核层过滤逻辑parse_tcp_mss(): TCP MSS 解析
位置: pkg/core/
职责:
- 事件结构定义和序列化
- 过滤配置解析和管理
- 数据包合并和格式化
- TCP 重传检测
- Netfilter 信息格式化
- 符号解析(调用栈)
关键模块:
event.go: 定义SoEvent结构,提供事件格式化方法packet_merger.go: 合并相同 packet ID 的数据包,生成函数链retransmission_detector.go: TCP 重传检测器filter.go: 过滤配置解析
位置: pkg/comm/color/
职责:
- 颜色输出管理
- 格式化规则定义
- 终端检测
关键模块:
manager.go: 颜色管理器,统一管理颜色输出formatter.go: 格式化器,应用颜色规则rules.go: 颜色规则定义(RST、TTL、MAC 厂商等)
位置: cmd/main.go
职责:
- 命令行参数解析
- eBPF 程序加载和链接
- Ring Buffer 事件读取和处理
- 输出格式化
- AI 诊断触发、会话续接和结果提示
关键流程:
- 解析命令行参数
- 加载 eBPF 程序规范(
.o文件) - 创建 eBPF 程序集合
- 附加 kprobe/kretprobe 到内核函数
- 读取 Ring Buffer 事件
- 格式化并输出 / 缓存抓包文本
- 结束抓包后触发 AI 诊断
- 输出摘要、抓包下载链接、诊断报告与会话文件
位置: pkg/diagnose/
职责:
- 缓存抓包原文,避免只依赖终端输出
- 生成本地统计摘要,构造 AI 提示词
- 上传完整抓包文本并调用云端 AI 接口
- 解析 AI 响应中的
answer、conversation_id等关键字段 - 写入诊断报告、原始响应文件和会话 ID 文件
关键模块:
capture.go: 将抓包输出双写到内存/临时文件,供结束后统一读取summary.go: 从抓包文本中提取统计指标和关键异常样本client.go: 负责文件上传、AI 请求、阻塞响应解析和会话续接report.go: 负责诊断报告生成,以及conversation_id的持久化
内核网络函数
↓
eBPF kprobe/kretprobe
↓
数据包解析 + 过滤
↓
Ring Buffer (事件)
↓
用户空间读取
↓
事件解析
↓
数据包合并(相同 packet ID)
↓
格式化输出(颜色、重传检测等)
↓
终端/文件输出 或 AI 缓存
↓
本地摘要生成
↓
完整抓包上传并获取下载链接
↓
云端 AI 阻塞式诊断
↓
解析 answer / conversation_id
↓
生成本地诊断报告 + 会话文件
- Linux 内核版本 >= 5.8(支持 eBPF CO-RE)
- Go 1.18+
- Clang 10+(用于编译 eBPF 程序)
- LLVM(用于编译 eBPF 程序)
- 需要 root 权限运行
使用 just 工具(推荐):
# 编译 eBPF 程序
just ebpf
# 或者手动编译
clang -g -O2 -mcpu=v2 -D__TARGET_ARCH_x86 -Wunused-command-line-argument -target bpf \
-I./ebpf/ -c ./ebpf/netbee.ebpf.c -o ./target/netbee.o使用 just 工具(推荐):
# 编译主程序
just build
# 或者手动编译
go build -o target/netbee ./cmd/main.go# 同时编译 eBPF 和 Go 程序
just ebpf && just build# 需要 root 权限
./target/netbee -h
网络数据包监控工具 - netbee
用法:
sudo ./target/netbee [选项]
协议过滤 (proto):
-proto string
过滤协议,逗号分隔 (tcp,udp,icmp)
主机过滤 (host):
-shost string
过滤来源主机IP地址
-dhost string
过滤目标主机IP地址
-host string
过滤主机IP地址 (来源或目标IP匹配即可)
端口过滤 (port):
-sport int
过滤来源端口
-dport int
过滤目的端口
-port int
过滤端口 (来源端口或目的端口匹配即可)
调试选项 (kfree):
-kfree
显示kfree_skb的调用栈信息
颜色输出选项:
-no-color
禁用颜色输出
数据包合并选项:
-ID
显示 packet ID,不进行合并(默认:合并相同 packet ID 的数据包)
包数量控制:
-c int
捕获指定数量的数据包后自动退出
示例: -c 100
输出文件选项:
-w string
将输出内容保存到指定文件
使用此选项时,终端不会显示抓包内容,且自动禁用颜色输出
示例: -w output.txt
其他选项:
-help
显示详细帮助信息(包含使用示例)# 监控所有 TCP 和 UDP 流量
sudo ./target/netbee -proto tcp,udp
# 监控特定主机的 ICMP 流量
sudo ./target/netbee -host 8.8.8.8 -proto icmp
# 监控 HTTP 流量(端口 80)
sudo ./target/netbee -proto tcp -dport 80
# 监控特定来源主机的所有流量
sudo ./target/netbee -shost 192.168.1.100
# 调试数据包丢弃(显示调用栈)
sudo ./target/netbee -kfree
# 组合过滤:监控特定主机到特定端口的 TCP 流量
sudo ./target/netbee -shost 192.168.1.1 -dport 80 -proto tcp
# 捕获 100 个数据包后自动退出
sudo ./target/netbee -c 100
# 将输出保存到文件(自动禁用颜色)
sudo ./target/netbee -w output.txt
# 显示 packet ID,不进行合并(每个事件单独显示)
sudo ./target/netbee -ID
# 抓取 100 个包后自动执行 AI 诊断
sudo NETBEE_AI_API_KEY=your-token ./target/netbee -c 100 -AI -ai-user xufanyun
# 指定 AI 报告文件名,并保存原始 AI 响应
sudo NETBEE_AI_API_KEY=your-token ./target/netbee -proto tcp -c 200 -AI -ai-user xufanyun -ai-out diagnosis.md -ai-raw-save当启用 -AI 后,NetBee 会在抓包结束时自动触发一次云端 AI 诊断。触发时机包括:
- 达到
-c指定的抓包数量后自动退出 - 用户按下
Ctrl+C - 程序正常结束
AI 诊断流程如下:
- 本地先根据抓包结果生成统计摘要
- 将完整抓包文本上传为临时文件,并把下载链接关联给 AI
- 以阻塞方式等待 AI 返回诊断结论
- 将完整结果写入本地
md或txt报告 - 在控制台打印诊断摘要、抓包文件下载链接和报告路径
-keep 模式下的会话处理规则如下:
- 先读取诊断报告同目录下保存的
conversation_id - 如果文件不存在,则直接按首次诊断处理
- 如果文件存在,则先调用
/messages做服务端预检 /messages预检通过时,才继续沿用历史会话- 如果
/messages明确返回会话无效或不存在,则自动按首次诊断处理 - 如果
/messages预检请求本身异常,终端会打印校验失败日志,随后仍会尝试沿用该会话,并由后续 AI 问答请求继续兜底
AI 问答请求默认带有自动重试机制:
- 仅对 AI 问答接口
chat-messages生效,不影响抓包采集和本地报告落盘逻辑 - 遇到网络错误、超时、
408、429、5xx等瞬时失败时,最多自动重试 3 次 - 每次失败、等待重试、重试成功、最终失败都会在终端输出明确日志,便于定位问题
- 对明显的参数错误(如
400 invalid_param)不会盲目重试,而是直接失败返回
启用 -AI 后的输出行为:
- 控制台默认不再实时输出抓包明细,避免大量刷屏
- 抓包原文仍会被完整采集,用于上传和生成诊断
- 如果同时指定
-w,抓包明细仍会额外写入你指定的文件
常用参数说明:
-AI:开启 AI 诊断-ai-user:AI 请求中的用户标识,建议传入真实域账号,例如xufanyun-ai-out:指定诊断报告输出路径,默认生成diagnosis-YYYYMMDD-HHMMSS.md-ai-timeout:AI 诊断总超时时间,默认120s-ai-raw-save:额外保存 AI 原始 JSON 响应,便于调试-keep:读取同目录下上次保存的conversation_id,先通过/messages预检合法性,再决定是否继续基于历史会话诊断-ai-api-key:直接传入 AI 鉴权 token;如果不传,则读取环境变量NETBEE_AI_API_KEY
推荐使用方式:
# 最常用:抓一定数量后自动出诊断
sudo NETBEE_AI_API_KEY=your-token ./target/netbee -c 100 -AI -ai-user xufanyun
# 排查 SSH/HTTP 等特定流量
sudo NETBEE_AI_API_KEY=your-token ./target/netbee -proto tcp -port 22 -c 200 -AI -ai-user xufanyun
# 诊断耗时较长时,适当增加超时
sudo NETBEE_AI_API_KEY=your-token ./target/netbee -proto tcp -c 300 -AI -ai-user xufanyun -ai-timeout 5m
# 延续上一次 AI 会话继续分析
sudo NETBEE_AI_API_KEY=your-token ./target/netbee -proto tcp -c 100 -AI -keep -ai-user xufanyun -ai-out diagnosis.md控制台示例:
2026/03/16 15:39:35 AI 模式已启用,控制台不再输出抓包明细
2026/03/16 15:39:50 开始执行 AI 诊断...
AI 诊断摘要:
1. 抓包概况
- 抓包文本大小: 154323 bytes
- 抓包有效行数: 842
- 协议分布: TCP=842, UDP=0, ICMP=0
- DROP 次数: 0
- TCP 重传次数: 117
- RST 次数: 0
2. 综合结论
- 回环链路与 SSH 会话均存在高密度 TCP 重传,但未见 DROP/RST,初步判断更像发送/接收端状态不一致或链路抖动后的重复发送。
2026/03/16 15:40:12 抓包文件下载链接: https://example.com/netbee-capture.txt
2026/03/16 15:40:12 AI 会话 ID 已保存: ./netbee-ai-conversation-id.txt
2026/03/16 15:40:12 AI 诊断完成,详细报告见: diagnosis-20260316-154012.md
如果 AI 问答接口出现瞬时异常,终端会输出类似下面的重试日志:
2026/03/17 11:20:01 开始执行 AI 诊断...
2026/03/17 11:20:18 AI 问答请求第 1/3 次失败: Post "https://dify.cvte.com/v1/chat-messages": context deadline exceeded;1s 后重试
2026/03/17 11:20:44 AI 问答请求第 2/3 次失败: AI 接口错误(502): bad gateway;2s 后重试
2026/03/17 11:21:05 AI 问答请求在第 3/3 次尝试后成功
2026/03/17 11:21:05 AI 诊断摘要:
...
如果连续重试仍失败,则会输出最终失败日志,例如:
2026/03/17 11:25:10 开始执行 AI 诊断...
2026/03/17 11:25:28 AI 问答请求第 1/3 次失败: Post "https://dify.cvte.com/v1/chat-messages": context deadline exceeded;1s 后重试
2026/03/17 11:25:55 AI 问答请求第 2/3 次失败: Post "https://dify.cvte.com/v1/chat-messages": context deadline exceeded;2s 后重试
2026/03/17 11:26:30 AI 问答请求连续 3 次失败,停止重试: Post "https://dify.cvte.com/v1/chat-messages": context deadline exceeded
2026/03/17 11:26:30 AI 诊断失败: Post "https://dify.cvte.com/v1/chat-messages": context deadline exceeded
基于真实运行结果,-keep 的效果通常分为两种:
此时程序不会报错,而是自动退化为首次诊断流程。控制台会明确提示“未找到上次 conversation_id 文件,按首次诊断处理”。
2026/03/17 10:00:57 开始执行 AI 诊断...
2026/03/17 10:00:57 未找到上次 conversation_id 文件,按首次诊断处理: netbee-ai-conversation-id.txt
2026/03/17 10:02:29 AI 诊断摘要:
2026/03/17 10:02:29 - 抓包文本大小: 37525 bytes
2026/03/17 10:02:29 - 抓包有效行数: 100
2026/03/17 10:02:29 - 协议分布: TCP=100, UDP=0, ICMP=0
2026/03/17 10:02:29 - DROP 次数: 0
2026/03/17 10:02:29 - TCP 重传次数: 86
2026/03/17 10:02:29 - RST 次数: 0
2026/03/17 10:02:29 综合结论
2026/03/17 10:02:29 1. 综合判断
2026/03/17 10:02:29 - 从抓包原文看,本次问题核心发生在“已建立 SSH 会话的数据传输阶段”,而不是握手、端口未开、防火墙丢包或连接重置。
2026/03/17 10:02:29 2. 已知异常
2026/03/17 10:02:29 - 外网 SSH 流 `58.248.106.93:2504 -> 172.18.178.174:22` 多次出现 `[TCP Retransmission]`。
2026/03/17 10:02:29 3. 最可能根因
2026/03/17 10:02:29 - 外部 SSH 网络路径存在瞬时丢包、抖动或乱序。
2026/03/17 10:02:29 ---
2026/03/17 10:02:29 抓包文件下载链接: https://tmp-aliyun-pub.oss-cn-hangzhou.aliyuncs.com/edge-script-pro/8538a4a5d8054a649ac2cf80be0b0f6b.txt
2026/03/17 10:02:29 AI 会话 ID 已保存: netbee-ai-conversation-id.txt
2026/03/17 10:02:29 AI 诊断完成,详细报告见: diagnosis.md
这一轮运行体现了以下效果:
- 即使命令里带了
-keep,在没有历史会话文件时,依然会自动按首次诊断提示词执行 - AI 摘要会先输出 6 项统计信息,再输出综合判断、已知异常、最可能根因
- 诊断结束后会同时产出抓包文件下载链接、诊断报告和新的
conversation_id文件
当同目录中已经存在 netbee-ai-conversation-id.txt 后,再次执行相同命令,程序会先通过 /messages 校验该会话;预检通过后,程序会继续沿用上次会话,并进入续聊提示词逻辑。
2026/03/17 10:05:40 开始执行 AI 诊断...
2026/03/17 10:05:40 继续使用上次 AI 会话: netbee-ai-conversation-id.txt
2026/03/17 10:07:03 AI 诊断摘要:
2026/03/17 10:07:03 - 抓包文本大小: 45848 bytes
2026/03/17 10:07:03 - 抓包有效行数: 100
2026/03/17 10:07:03 - 协议分布: TCP=96, UDP=0, ICMP=0
2026/03/17 10:07:03 - DROP 次数: 0
2026/03/17 10:07:03 - TCP 重传次数: 81
2026/03/17 10:07:03 - RST 次数: 0
2026/03/17 10:07:03 综合结论
2026/03/17 10:07:03 1. 综合判断
2026/03/17 10:07:03 - 这是对同一问题的续查,本次抓包与上次总体一致,应判定为“延续并增强证据”,而不是推翻原判断。
2026/03/17 10:07:03 2. 与上次相比
2026/03/17 10:07:03 - 延续:未见 DROP、未见 RST、Seq/Ack 持续推进,问题仍不是握手失败或防火墙拦截。
2026/03/17 10:07:03 - 修正:loopback 上的“重传”不能再简单全部归因于 netbee 多点采样放大。
2026/03/17 10:07:03 - 仍待确认:eth0 上 `2504->22`、`2505->22` 的 `[TCP Retransmission]` 是否在普通 pcap/tcpdump 中同样成立。
2026/03/17 10:07:03 3. 已知异常
2026/03/17 10:07:03 - 外部 `58.248.106.93 -> 172.18.178.174:22` 的 SSH 流再次出现多次 `[TCP Retransmission]`。
2026/03/17 10:07:03 4. 最可能根因
2026/03/17 10:07:03 - 外部 SSH 网络路径存在持续轻度丢包、乱序或抖动。
2026/03/17 10:07:03 ---
2026/03/17 10:07:03 抓包文件下载链接: https://tmp-aliyun-pub.oss-cn-hangzhou.aliyuncs.com/edge-script-pro/dcfa93e7c9dc4f608b1532ee3971531c.txt
2026/03/17 10:07:03 AI 会话 ID 已保存: netbee-ai-conversation-id.txt
2026/03/17 10:07:03 AI 诊断完成,详细报告见: diagnosis.md
这一轮运行体现了 -keep 的核心价值:
- AI 会基于上一次的
conversation_id继续分析,而不是把问题当作全新抓包重新归纳 - 续聊摘要会新增“与上次相比”这一段,明确区分延续、修正和仍待确认的判断
- 适合对同一问题连续多次抓包,逐步增强证据、修正判断并验证修复效果
这种情况通常出现在会话已失效、user 变化、Dify 侧已经查不到该会话等场景。程序会在终端打印预检无效日志,然后自动退化为首次诊断,而不是直接报错中断。
2026/03/17 12:10:01 开始执行 AI 诊断...
2026/03/17 12:10:01 检测到上次 AI 会话文件,准备校验合法性: netbee-ai-conversation-id.txt
2026/03/17 12:10:02 conversation_id 预检无效,按首次诊断处理: 45701982-8118-4bc5-8e9b-64562b4555f2
2026/03/17 12:10:45 AI 诊断摘要:
...
这个场景说明:
-keep不是“只要本地文件有值就盲目续聊”- 当前实现会先以服务端
/messages的结果作为准入判断 - 只有服务端确认该会话仍可用时,才会真正进入续聊模式
生成的诊断报告通常包含以下内容:
- 基本信息:运行命令、开始/结束时间、统计摘要、抓包文件下载链接
- AI 诊断结果:按固定章节输出综合结论、已知异常、最可能根因、建议动作等内容
- AI 调用元数据:任务 ID、
conversation_id、耗时、token 消耗、是否走文件上传等调试信息 - 会话状态文件:保存
conversation_id,供下次-keep续聊使用
协议过滤:
-proto string: 过滤协议,逗号分隔(tcp,udp,icmp)
主机过滤:
-shost string: 过滤来源主机 IP 地址-dhost string: 过滤目标主机 IP 地址-host string: 过滤主机 IP 地址(来源或目标 IP 匹配即可)
端口过滤:
-sport int: 过滤来源端口-dport int: 过滤目的端口-port int: 过滤端口(来源端口或目的端口匹配即可)
调试选项:
-kfree: 显示 kfree_skb 的调用栈信息(用于调试数据包丢弃原因)
输出选项:
-no-color: 禁用颜色输出-w string: 将输出内容保存到指定文件(自动禁用颜色)-c int: 捕获指定数量的数据包后自动退出-ID: 显示 packet ID,不进行合并(默认:合并相同 packet ID 的数据包)-AI: 抓包结束时调用云端 AI 诊断,并将结果写入本地报告-ai-user string: AI 诊断请求中的user字段-ai-out string: AI 诊断报告输出路径(默认按时间戳生成.md文件)-ai-timeout duration: AI 诊断接口总超时时间-ai-raw-save: 保存 AI 原始响应 JSON 文件,便于调试-keep: 读取同目录上次保存的conversation_id,继续基于历史会话诊断-ai-api-key string: AI 接口鉴权 token(默认读取NETBEE_AI_API_KEY)-help: 显示详细帮助信息
Time SrcIP DstIP Protocol Length SrcMAC TTL Info
---- ----- ----- -------- ------ ------ --- ----
11:32:02.628 183.63.127.84 172.26.220.143 TCP 0 ee:ff:ff:ff:ff:ff 51 2079->8888 SYN Seq:449478215 Ack:0 MSS:1456 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow] PID:0 NF:LOCAL_IN:DROP
11:32:03.598 172.26.220.143 183.63.127.84 TCP 0 b4:ff:ff:00:90:86 64 8888->2079 SYN,ACK Seq:930768552 Ack:449478216 MSS:1460 eth0 [nf_hook_slow->dev_queue_xmit] PID:0
11:32:03.608 183.63.127.84 172.26.220.143 TCP 0 ee:ff:ff:ff:ff:ff 51 [TCP Retransmission] 2079->8888 SYN Seq:449478215 Ack:0 MSS:1456 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow->tcp_v4_rcv] PID:0
11:32:04.086 183.63.127.84 172.26.220.143 TCP 8 ee:ff:ff:ff:ff:ff 51 2079->8888 PSH,ACK Seq:449478216 Ack:930768553 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow->ip_rcv->ip_local_deliver->nf_hook_slow->ip_rcv->ip_local_deliver->nf_hook_slow->ip_rcv->ip_local_deliver->nf_hook_slow->tcp_v4_rcv->kfree_skb] PID:1822221=nc(nc -lvkp 8888)
11:32:04.188 172.26.220.143 183.63.127.84 TCP 0 84:24:e8:0d:00:00 64 8888->2079 ACK Seq:930768553 Ack:449478224 eth0 [nf_hook_slow->dev_queue_xmit] PID:0
11:32:04.788 183.63.127.84 172.26.220.143 TCP 12 ee:ff:ff:ff:ff:ff 51 2079->8888 PSH,ACK Seq:449478224 Ack:930768553 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow] PID:0 NF:LOCAL_IN:DROP
11:32:04.848 183.63.127.84 172.26.220.143 TCP 12 ee:ff:ff:ff:ff:ff 51 [TCP Retransmission] 2079->8888 PSH,ACK Seq:449478224 Ack:930768553 [ip_rcv->ip_local_deliver->nf_hook_slow->tcp_v4_rcv->kfree_skb] PID:1822221=nc(nc -lvkp 8888)
11:32:04.958 172.26.220.143 183.63.127.84 TCP 0 b4:ff:ff:00:90:86 64 8888->2079 ACK Seq:930768553 Ack:449478236 eth0 [nf_hook_slow->dev_queue_xmit] PID:0
11:32:05.858 183.63.127.84 172.26.220.143 TCP 10 ee:ff:ff:ff:ff:ff 51 2079->8888 PSH,ACK Seq:449478236 Ack:930768553 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow] PID:0 NF:LOCAL_IN:DROP
11:32:05.998 183.63.127.84 172.26.220.143 TCP 10 ee:ff:ff:ff:ff:ff 51 [TCP Retransmission] 2079->8888 PSH,ACK Seq:449478236 Ack:930768553 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow] PID:0 NF:LOCAL_IN:DROP
11:32:06.317 183.63.127.84 172.26.220.143 TCP 10 ee:ff:ff:ff:ff:ff 51 [TCP Retransmission] 2079->8888 PSH,ACK Seq:449478236 Ack:930768553 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow] PID:0 NF:LOCAL_IN:DROP
11:32:06.768 183.63.127.84 172.26.220.143 TCP 10 ee:ff:ff:ff:ff:ff 51 [TCP Retransmission] 2079->8888 PSH,ACK Seq:449478236 Ack:930768553 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow] PID:0 NF:LOCAL_IN:DROP
11:32:07.346 183.63.127.84 172.26.220.143 TCP 10 ee:ff:ff:ff:ff:ff 51 [TCP Retransmission] 2079->8888 PSH,ACK Seq:449478236 Ack:930768553 [ip_rcv->ip_local_deliver->nf_hook_slow->tcp_v4_rcv->kfree_skb] PID:1822221=nc(nc -lvkp 8888)
11:32:07.447 172.26.220.143 183.63.127.84 TCP 0 20:61:74:20:65:78 64 8888->2079 ACK Seq:930768553 Ack:449478246 eth0 [nf_hook_slow->dev_queue_xmit] PID:0
11:32:24.553 183.63.127.84 172.26.220.143 TCP 0 ee:ff:ff:ff:ff:ff 51 2079->8888 FIN,ACK Seq:449478246 Ack:930768553 [ip_rcv->ip_local_deliver->nf_hook_slow->tcp_v4_rcv->kfree_skb] PID:1822221=nc(nc -lvkp 8888)
11:32:24.657 172.26.220.143 183.63.127.84 TCP 0 84:24:e8:0d:00:00 64 8888->2079 FIN,ACK Seq:930768553 Ack:449478247 eth0 [nf_hook_slow->dev_queue_xmit] PID:1822221=nc(nc -lvkp 8888)
11:32:24.668 183.63.127.84 172.26.220.143 TCP 0 ee:ff:ff:ff:ff:ff 51 2079->8888 ACK Seq:449478247 Ack:930768554 eth0 [ip_rcv->ip_local_deliver->nf_hook_slow] PID:0 NF:LOCAL_IN:DROP
11:32:26.088 172.26.220.143 183.63.127.84 TCP 0 84:24:e8:0d:00:00 64 [TCP Retransmission] 8888->2079 FIN,ACK Seq:930768553 Ack:449478247 eth0 [nf_hook_slow->dev_queue_xmit] PID:0
11:32:26.116 183.63.127.84 172.26.220.143 TCP 0 ee:ff:ff:ff:ff:ff 51 [TCP Retransmission] 2079->8888 ACK Seq:449478247 Ack:930768554 [ip_rcv->ip_local_deliver->nf_hook_slow->tcp_v4_rcv->kfree_skb] PID:0
- Time: 时间戳
- SrcIP: 源 IP 地址
- DstIP: 目标 IP 地址
- Protocol: 协议类型(TCP、UDP、ICMP)
- Length: 数据包长度
- SrcMAC: 源 MAC 地址(可能包含厂商名称)
- TTL: IP 包的 TTL 值
- Info: 详细信息
- 端口信息(源端口->目标端口)
- TCP 标志(SYN、ACK、RST 等)
- Seq 和 Ack 序列号
- 函数链(数据包经过的内核函数)
- 进程信息(PID、进程名)
- Netfilter 信息(钩子点、处理结果)
- 红色: RST 标志、TCP 重传的 Seq/Ack、NF DROP、
[TCP Retransmission]标记 - 黄色: TTL > 100、MAC 厂商名称
- 使用
-kfree参数查看数据包丢弃的调用栈 - 使用
-ID参数查看每个事件的详细信息 - 使用
-w参数保存输出到文件,便于后续分析
本项目采用 Dual BSD/GPL 许可证。