Skip to content

stefanxfy/netbee

Repository files navigation

NetBee

基于 eBPF 的网络全链路排查工具,支持 AI 诊断闭环分析

0. 功能介绍与项目背景

为什么用 eBPF 开发网络链路排查工具

在实际网络排查中,我们经常遇到以下问题:

  1. 安全进程 EDR 在内核中拦截网络:传统的网络抓包工具(如 tcpdump)无法捕获内核层面的网络拦截行为,导致无法定位数据包在哪个环节被丢弃。

  2. 全链路跟踪困难:tcpdump 基于 TC(Traffic Control)模块实现抓包,只能捕获网络接口层面的数据包,无法跟踪数据包在内核网络栈中的完整路径。

  3. 本地防火墙链路不可见:无法抓取 Netfilter 框架中的处理流程,包括防火墙规则、NAT 转换等关键环节。

  4. 进程关联困难:无法直接关联网络流量与用户进程,难以定位是哪个进程产生的流量。

  5. 抓包结果解读成本高:即使拿到了完整链路和异常样本,排障人员仍需要手工梳理统计信息、异常模式和可能根因,分析效率依赖经验。

与 tcpdump 的对比

特性 NetBee tcpdump
抓包方式 eBPF kprobe/kretprobe TC 模块
网络栈覆盖 全链路(从网卡到应用层) 仅网络接口层
内核拦截可见 ✅ 可捕获内核拦截点 ❌ 不可见
Netfilter 跟踪 ✅ 支持(PRE_ROUTING、LOCAL_IN、FORWARD、LOCAL_OUT、POST_ROUTING) ❌ 不支持
输出格式 ✅ 可视化表格,无需 Wireshark ❌ 需要 Wireshark 分析
调用栈跟踪 ✅ 支持(kfree_skb 调用栈) ❌ 不支持
实时过滤 ✅ 内核层过滤,性能高 ✅ 支持

核心功能

  1. 全链路网络跟踪

    • 跟踪数据包从网卡接收(netif_rx)到应用层处理(tcp_v4_rcvudp_rcv)的完整路径
    • 支持 Netfilter 五个钩子点的跟踪(PRE_ROUTING、LOCAL_IN、FORWARD、LOCAL_OUT、POST_ROUTING)
    • 显示数据包经过的内核函数链
  2. 可视化输出

    • 表格化输出,无需借助 Wireshark 分析
    • 颜色标记:RST 标志显示红色,TCP 重传显示红色,NF DROP 显示红色
    • 自动合并相同 packet ID 的数据包,显示完整路径
  3. 进程信息抓取

    • 自动关联网络流量与用户进程(PID、进程名)
    • 支持调用栈跟踪(-kfree 参数)
  4. TCP 重传检测

    • 基于 Seq 和 Ack 自动识别 TCP 重传
    • 重传包显示 [TCP Retransmission] 标记,Seq 和 Ack 显示红色
  5. 灵活的过滤功能

    • 协议过滤(TCP、UDP、ICMP)
    • 主机过滤(源 IP、目标 IP、任意 IP)
    • 端口过滤(源端口、目标端口、任意端口)
    • 内核层过滤,性能高
  6. Netfilter 信息

    • 显示数据包经过的 Netfilter 钩子点
    • 显示处理结果(ACCEPT、DROP、OTHER)
    • DROP 结果自动标记为红色
  7. AI 诊断报告

    • 使用 -AI 在抓包结束后自动调用云端 AI 进行诊断
    • 自动生成抓包摘要、上传完整抓包文本,并输出本地 Markdown/TXT 报告
    • 控制台打印诊断摘要、抓包文件下载链接和详细报告路径,便于快速分享与复盘
    • 保存 conversation_id,支持基于历史诊断结果继续追问和多轮分析

AI 的作用

NetBee 不只是“抓到包”,更强调“把抓到的链路信息转成可执行结论”。AI 在整个排障流程中的作用主要体现在:

  1. 把原始抓包转成诊断结论

    • 自动归纳抓包概况、协议分布、DROP/RST/重传等关键统计
    • 从大量链路明细中提炼综合结论、已知异常、最可能根因和建议动作
  2. 降低排障门槛

    • 一线同学无需手工阅读长篇抓包文本,也能快速获得可读结论
    • 将“看懂内核链路”转化为“先读诊断摘要,再看详细报告”
  3. 形成排障闭环

    • 抓包结束即可自动出报告,无需再手工整理材料
    • 控制台、抓包下载链接、本地诊断报告三者联动,方便团队协作和问题复盘
  4. 支持连续追问

    • 保存 AI 返回的 conversation_id
    • 后续通过 -keep 基于上次会话继续分析,适合二次排查、补充抓包、验证修复效果

1. 项目架构设计

整体架构

┌─────────────────────────────────────────────────────────────┐
│                     用户空间 (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 诊断设计

AI 诊断被设计成 NetBee 的后处理分析链路,而不是独立外挂脚本。其设计目标是:在不影响原始抓包能力的前提下,把原始事件流自动转成一份可交付、可追问、可复盘的诊断结果。

核心设计点如下:

  1. 采集与展示解耦

    • 抓包明细可以不在控制台实时刷出,但原始文本仍会完整缓存
    • 这样既避免大流量场景下终端刷屏,也保证 AI 诊断使用的是完整抓包内容
  2. 摘要 + 全量原文双轨输入

    • 本地先提取抓包大小、协议分布、DROP/RST/重传次数、关键异常样本等摘要
    • 同时上传完整抓包原文,让 AI 既能快速理解全局,也能回看细节
  3. 阻塞式诊断输出

    • 抓包结束后同步等待 AI 返回结果
    • 保证控制台提示、抓包链接、诊断报告三者在一次执行中闭环产出
  4. 报告与会话状态落盘

    • AI 结果会落成本地报告文件
    • conversation_id 会额外保存到与报告同目录的固定文件中,便于后续续聊
  5. 支持连续排障

    • 使用 -keep 时,会自动读取上次保存的 conversation_id
    • 在真正续聊前,会先调用 /messages 对该 conversation_id 做服务端预检
    • 只有预检通过时才沿用历史会话;若会话不存在或无效,则自动退化为首次诊断
    • 适合“第一次抓包得到初判 -> 第二次补抓后继续追问 -> 第三次验证修复效果”的连续分析流程

AI 提示词设计思想

NetBee 的 AI 提示词不是简单的一句“帮我分析抓包”,而是围绕“稳定输出、强制看原文、支持连续问答”三个目标设计的。

1. 首次诊断提示词设计思想

首次诊断对应普通 -AI 模式,设计目标是让 AI 在第一次看到抓包时,快速完成“从原始抓包到诊断结论”的首轮归纳。

设计重点:

  • 先定输出结构:强制 AI 使用固定 Markdown 章节,保证控制台摘要提取和报告展示稳定
  • 强调原文优先:明确要求 AI 必须分析上传的抓包文件原文,不能只复述本地摘要
  • 证据驱动结论:要求 AI 在“关键证据”“综合判断”中体现抓包中的协议分布、报文方向、重传、DROP、RST、函数链路、进程信息等证据
  • 不确定就明确说:如果抓包证据不足,必须输出“证据不足”或“仍需进一步验证”,避免把猜测当作结论
  • 从首诊角度组织内容:更关注“整个链路发生了什么”“最可能根因是什么”“建议先做什么排查”

2. -keep 续聊提示词设计思想

-keep 模式不是重新起一个全新问题,而是基于历史会话继续追问同一个网络问题,因此提示词设计重点从“首诊归纳”转为“增量分析”。

设计重点:

  • 基于历史上下文继续分析:明确告诉 AI 当前不是首次诊断,而是基于之前的 conversation_id 延续分析
  • 本次抓包优先级最高:即使历史结论已经存在,只要本次上传的抓包原文和历史判断冲突,也必须以本次抓包原文为准
  • 必须说明变化关系:强制 AI 明确说明本次相较上次是“延续”“修正”还是“推翻”
  • 突出增量价值:关注“本次新增了什么现象”“相比上一轮结论哪里更确定、哪里被修正”
  • 适合多轮排障闭环:第一次用于初判,第二次用于补证据,第三次可用于验证修复效果

3. 提示词、问答上下文与抓包原文如何配合

AI 诊断并不是只靠一段提示词完成,而是三类输入一起工作:

  1. 提示词(Query)

    • 告诉 AI 角色、输出格式、判断规则和硬约束
    • 决定 AI 输出是否稳定、是否聚焦网络排障、是否优先看原文
  2. 会话上下文(conversation_id

    • 只在 -keep 时参与
    • 让 AI 能继承上一轮结论、追问记录和判断路径
    • 用于回答“这次和上次相比发生了什么变化”
    • 在使用前会先通过 /messages 做一次合法性校验,避免把失效会话直接传给 AI
  3. 本次抓包输入

    • 包括本地提取的摘要,以及上传的完整抓包文件原文
    • 摘要用于快速告诉 AI 关键统计信息
    • 抓包文件原文用于真正支撑证据和结论

三者分工如下:

  • 提示词负责“规定怎么答”
  • 历史会话负责“继承之前答过什么”
  • 抓包原文负责“决定这次到底看到了什么证据”

因此,NetBee 的设计原则是:

  • 摘要只是导航,不是最终依据
  • 历史结论只是背景,不是绝对真相
  • 本次抓包原文才是最终判断依据

4. 当前使用的原始提示词

下面是当前代码中实际使用的两套提示词模板。

首次诊断提示词(普通 -AI
你是一名资深网络排障工程师,请根据 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]
续聊提示词(-AI -keep
你是一名资深网络排障工程师,当前不是首次分析,而是基于之前会话继续诊断同一个网络问题。

硬约束:
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]

代码分层

1. 内核层(eBPF)

位置: ebpf/netbee.ebpf.c

职责:

  • 在内核关键网络函数处插入探针(kprobe/kretprobe)
  • 解析网络数据包(以太网、IP、TCP/UDP)
  • 执行内核层过滤(减少用户空间开销)
  • 通过 Ring Buffer 将事件发送到用户空间

关键函数:

  • do_trace_skb(): 核心的数据包解析和事件生成函数
  • apply_filters(): 内核层过滤逻辑
  • parse_tcp_mss(): TCP MSS 解析

2. 核心层(Core)

位置: pkg/core/

职责:

  • 事件结构定义和序列化
  • 过滤配置解析和管理
  • 数据包合并和格式化
  • TCP 重传检测
  • Netfilter 信息格式化
  • 符号解析(调用栈)

关键模块:

  • event.go: 定义 SoEvent 结构,提供事件格式化方法
  • packet_merger.go: 合并相同 packet ID 的数据包,生成函数链
  • retransmission_detector.go: TCP 重传检测器
  • filter.go: 过滤配置解析

3. 通信层(Comm)

位置: pkg/comm/color/

职责:

  • 颜色输出管理
  • 格式化规则定义
  • 终端检测

关键模块:

  • manager.go: 颜色管理器,统一管理颜色输出
  • formatter.go: 格式化器,应用颜色规则
  • rules.go: 颜色规则定义(RST、TTL、MAC 厂商等)

4. 应用层(Cmd)

位置: cmd/main.go

职责:

  • 命令行参数解析
  • eBPF 程序加载和链接
  • Ring Buffer 事件读取和处理
  • 输出格式化
  • AI 诊断触发、会话续接和结果提示

关键流程:

  1. 解析命令行参数
  2. 加载 eBPF 程序规范(.o 文件)
  3. 创建 eBPF 程序集合
  4. 附加 kprobe/kretprobe 到内核函数
  5. 读取 Ring Buffer 事件
  6. 格式化并输出 / 缓存抓包文本
  7. 结束抓包后触发 AI 诊断
  8. 输出摘要、抓包下载链接、诊断报告与会话文件

5. AI 诊断层(Diagnose)

位置: pkg/diagnose/

职责:

  • 缓存抓包原文,避免只依赖终端输出
  • 生成本地统计摘要,构造 AI 提示词
  • 上传完整抓包文本并调用云端 AI 接口
  • 解析 AI 响应中的 answerconversation_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
    ↓
生成本地诊断报告 + 会话文件

2. 项目构建与执行

环境要求

  • Linux 内核版本 >= 5.8(支持 eBPF CO-RE)
  • Go 1.18+
  • Clang 10+(用于编译 eBPF 程序)
  • LLVM(用于编译 eBPF 程序)
  • 需要 root 权限运行

构建步骤

1. 编译 eBPF 程序

使用 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

2. 编译 Go 程序

使用 just 工具(推荐):

# 编译主程序
just build

# 或者手动编译
go build -o target/netbee ./cmd/main.go

3. 一键构建

# 同时编译 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 诊断说明

当启用 -AI 后,NetBee 会在抓包结束时自动触发一次云端 AI 诊断。触发时机包括:

  • 达到 -c 指定的抓包数量后自动退出
  • 用户按下 Ctrl+C
  • 程序正常结束

AI 诊断流程如下:

  1. 本地先根据抓包结果生成统计摘要
  2. 将完整抓包文本上传为临时文件,并把下载链接关联给 AI
  3. 以阻塞方式等待 AI 返回诊断结论
  4. 将完整结果写入本地 mdtxt 报告
  5. 在控制台打印诊断摘要、抓包文件下载链接和报告路径

-keep 模式下的会话处理规则如下:

  • 先读取诊断报告同目录下保存的 conversation_id
  • 如果文件不存在,则直接按首次诊断处理
  • 如果文件存在,则先调用 /messages 做服务端预检
  • /messages 预检通过时,才继续沿用历史会话
  • 如果 /messages 明确返回会话无效或不存在,则自动按首次诊断处理
  • 如果 /messages 预检请求本身异常,终端会打印校验失败日志,随后仍会尝试沿用该会话,并由后续 AI 问答请求继续兜底

AI 问答请求默认带有自动重试机制:

  • 仅对 AI 问答接口 chat-messages 生效,不影响抓包采集和本地报告落盘逻辑
  • 遇到网络错误、超时、4084295xx 等瞬时失败时,最多自动重试 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

AI 使用效果

控制台示例:

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 的效果通常分为两种:

场景 1:首次使用 -keep,但本地还没有 conversation_id 文件

此时程序不会报错,而是自动退化为首次诊断流程。控制台会明确提示“未找到上次 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 文件
场景 2:第二次使用 -keep/messages 预检通过后继续分析

当同目录中已经存在 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 继续分析,而不是把问题当作全新抓包重新归纳
  • 续聊摘要会新增“与上次相比”这一段,明确区分延续、修正和仍待确认的判断
  • 适合对同一问题连续多次抓包,逐步增强证据、修正判断并验证修复效果
场景 3:存在 conversation_id 文件,但 /messages 预检判定会话无效

这种情况通常出现在会话已失效、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 许可证。

About

基于ebpf的网络排查工具

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages