Yara-hneif/network-analyzer

GitHub: Yara-hneif/network-analyzer

基于C++17多线程架构和Welford流式算法的实时网络数据包分析器,以O(1)内存开销检测DDoS等流量统计异常。

Stars: 0 | Forks: 0

# 🛡️ 高性能多线程网络分析器与异常检测器 ![C++17](https://img.shields.io/badge/C%2B%2B-17-blue.svg) ![Linux](https://img.shields.io/badge/Platform-Linux%20%2F%20POSIX-orange.svg) ![Build](https://img.shields.io/badge/Build-CMake%203.14%2B-green.svg) ![License](https://img.shields.io/badge/License-MIT-brightgreen.svg) 一个使用现代 **C++17** 编写的、企业级的实时网络流量分析引擎。该系统能够高速捕获实时原始网络数据包,通过解耦的**生产者-消费者 pipeline** 在多核处理器上并发处理请求头,并利用 **Welford's Streaming Algorithm** 在 **$O(1)$ 内存复杂度**下检测统计流量异常(例如 DDoS 激增或数据包泛洪)。 ## 📖 目录 1. [执行摘要与问题陈述](#-1-executive-summary--problem-statement) 2. [架构解决方案](#-2-the-architectural-solution) 3. [系统架构与数据流](#-3-system-architecture--data-flow) 4. [项目结构与布局](#-4-project-structure--layout) 5. [引擎工作原理:简单类比与数学直觉](#-5-how-the-engine-works-simple-analogy--mathematical-intuition) 5.1. [理解数学原理(简单版)](#-understanding-the-mathematics-made-simple) 5.2 [核心算法简化(面向所有人)](#-5-simplifying-the-core-algorithms-for-everyone) - [A. 现实世界类比](#a-real-world-analogy-airport-cargo-inspection) - [B. Welford's Algorithm($O(1)$ 内存空间)](#b-welfords-algorithm-o1-memory-space) - [C. Z-Score 统计阈值](#c-z-score-statistical-thresholding) - [D. 生产者-消费者模式与背压](#d-producer-consumer-pattern--backpressure) 6. [构建与运行项目](#-6-building--running-the-project) 7. [运行自动化测试套件](#-7-running-the-automated-test-suite) 8. [性能与线程安全保证](#-8-performance--thread-safety-guarantees) 9. [关键 C++17 工程概念](#-9-key-c17-engineering-concepts) 10. [作者与许可证](#-10-author--license) ## 📌 1. 执行摘要与问题陈述 ### 🔍 问题背景 在现代数据中心和云基础设施中,网络流量以每秒数百万个数据包的速度传输。检测诸如 **DDoS(分布式拒绝服务攻击)**、**数据包泛洪**或**数据泄露**等威胁需要实时分析数据包头。 传统的简单方法面临三个关键工程瓶颈: 1. **I/O 瓶颈:** 在同一线程上解析数据包并运行繁重的统计分析会导致丢包(*Packet Loss*),因为接口接收数据的速度超过了应用程序处理数据的速度。 2. **内存瓶颈:** 计算历史数据包的统计指标(如平均值和标准差)通常需要在内存中存储较长的历史窗口——导致 $O(N)$ 的内存增长,并最终引发 **Out-Of-Memory (OOM) 崩溃**。 3. **不安全关闭问题:** 使用 `Ctrl + C` 强制关闭网络监控工具可能会导致网卡(NIC)冻结或破坏活跃的内存 socket。 ## 💡 2. 架构解决方案 为了解决这三个瓶颈,该引擎使用现代 `C++17` 并发最佳实践和在线流式数学计算,将数据包捕获与分析处理解耦: 1. **解耦的生产者-消费者架构:** * **生产者线程 (`PacketIngestor`):** 使用 `libpcap` 在混杂模式下捕获原始网络帧,并将轻量级的 `PacketMetadata` DTO 直接推送到线程安全的有界队列中。网络捕获线程永远不会暂停或等待分析! * **消费者线程 (`AnomalyDetector`):** 在后台并发运行,从队列中提取数据包以执行统计检查,而不会冻结网络接口或导致丢包。 2. **有界背压流控制:** 线程安全队列强制执行固定的容量限制。如果在流量激增期间处理线程落后,缓冲区会安全地暂停生产者,以防止内存膨胀和 **Out-Of-Memory (OOM)** 崩溃。 3. **$O(1)$ 流式数学计算 (Welford's Algorithm):** 在恒定内存空间($O(1)$)中持续计算运行平均值和方差,无需存储过去的数据包历史记录——从而确保无论系统运行 5 秒还是 5 年,内存使用量都保持平稳。 4. **POSIX 信号处理(优雅关闭):** 拦截系统终止信号(`SIGINT`/`SIGTERM`),以安全解除阻塞所有线程、刷新内存队列、关闭原始句柄,并在零资源泄漏的情况下退出。 ## 🏗️ 3. 系统架构与数据流 以下是展示原始硬件信号如何通过我们的软件 pipeline 的概念架构: ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ PHYSICAL NETWORK CARD (NIC) │ └──────────────────────────────────────┬──────────────────────────────────────┘ │ Raw Network Frames ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ PRODUCER THREAD (PacketIngestor) │ │ - Promiscuous Mode (libpcap) │ │ - Offsets Ethernet Header (14 bytes) -> Extracts IPv4 Headers │ │ - Strips Payload, keeps lightweight PacketMetadata DTO │ └──────────────────────────────────────┬──────────────────────────────────────┘ │ PacketMetadata (Pushed) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ BOUNDED THREAD-SAFE QUEUE (Buffer) │ │ - Synchronized via std::mutex & std::condition_variable │ │ - Prevents OOM via Backpressure Mechanism │ └──────────────────────────────────────┬──────────────────────────────────────┘ │ PacketMetadata (Popped) ▼ ┌─────────────────────────────────────────────────────────────────────────────┐ │ CONSUMER THREAD (AnomalyDetector) │ │ - Calculates Streaming Mean & StdDev via Welford's Algorithm ($O(1)$) │ │ - Calculates Z-Score per packet │ │ - If Z-Score > 3.0 -> Triggers Colorized Console Log Alert (Logger) │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ## 📂 4. 项目结构与架构 ``` NetworkAnalyzer/ ├── CMakeLists.txt # Production-grade CMake build script with CTest ├── include/ │ ├── PacketMetadata.hpp # Lightweight DTO holding extracted packet features │ ├── ThreadSafeQueue.hpp # Bounded thread-safe FIFO queue with Backpressure │ ├── PacketIngestor.hpp # RAII wrapper around libpcap raw network sockets │ ├── AnomalyDetector.hpp # Thread-safe streaming Welford anomaly engine │ └── Logger.hpp # Synchronized, color-coded thread-safe logging framework ├── src/ │ ├── PacketIngestor.cpp # Promiscuous interface binding & offset parsing │ ├── AnomalyDetector.cpp # Online Welford & Z-score implementation │ ├── Logger.cpp # ANSI color-coded stdout logger │ └── main.cpp # Multi-threaded entry point with POSIX Signal Handler ├── tests/ │ ├── test_packet_ingestor.cpp # Unit test for metadata integrity │ ├── test_thread_safe_queue.cpp # Concurrent stress test for queue synchronization │ ├── test_anomaly_detector.cpp # Mathematical validation of Welford & Z-Score │ └── test_integration_pipeline.cpp # End-to-End multi-threaded integration pipeline └── README.md # Project documentation ``` ## 💡 5. 引擎工作原理:简单类比与数学直觉 ## 🧮 理解数学原理(简单版) 即使您没有统计学背景,也可以通过三个基本问题来理解该核心算法: ### 1. 什么是正常流量?(运行平均值与方差) 无需保留所有过去数据包大小的列表(例如 `[64, 64, 128, 64, ...]`): * **Welford's Algorithm** 仅跟踪**三个数字**: * `count`:目前看到的数据包总数。 * `mean`:当前的平均数据包大小。 * `M2`:与平均值差的平方的累计总和。 每当一个新的数据包到达时,该算法就会在 $O(1)$ 的恒定时间和 $O(1)$ 的恒定内存空间内立即更新平均值和方差。 ### 2. 我们如何发现异常?($Z\text{-Score}$) $Z\text{-score}$ 衡量数据包大小($x$)偏离历史平均值($\mu$)的标准差个数: $$\text{Z-Score} = \frac{x - \mu}{\sigma}$$ * **正常范围:** $Z\text{-Score} \le 3.0$(根据正态高斯分布,包含 99.73% 的标准网络行为)。 * **异常标志:** $Z\text{-Score} > 3.0$(数据包大小或数据包频率出现激增,表明存在潜在的 DDoS 或异常)。 ### 3. 防止误报(冷启动保护) 在执行的前几秒钟(数据包少于 30 个)内,引擎会抑制警报。这为统计模型在标记异常值之前建立可靠的基准提供了时间。 ## 🧠 核心算法简化(面向所有人) ### A. 现实世界类比(机场货物检查) 想象一个繁忙的国际机场,每分钟都有成千上万的行李箱到达: * **没有我们的系统(传统方式):** 一名保安站在机舱门口。他接过一个行李箱,打开它,进行测量,将其重量与今天到达的所有行李箱进行对比计算,并写下一份报告。与此同时,另外 100 架飞机正在空中盘旋等待,因为保安太慢了。行李箱都弄丢了! * **使用我们的系统(我们的设计):** * **接收保安(生产者):** 站在机舱门口。他只需在每个行李箱上贴上一张便利贴(IP 地址、大小、时间戳),然后将其扔到传送带(`ThreadSafeQueue`)上。他一刻也不停歇! * **分析保安(消费者):** 站在传送带的尽头。他阅读便利贴,在一块小白板上更新他的连续计数器,并立即将行李箱从传送带上清空。如果突然出现一个重达 500 公斤的巨大行李箱,他就会吹响警哨(异常警报!)。 ### B. Welford's Algorithm($O(1)$ 内存空间) **所使用的数学公式:** $$\Delta = x_n - \mu_{n-1}$$ $$\mu_n = \mu_{n-1} + \frac{\Delta}{n}$$ $$M_{2,n} = M_{2,n-1} + \Delta \times (x_n - \mu_n)$$ $$\text{Variance} (\sigma^2) = \frac{M_{2,n}}{n - 1} \quad \implies \quad \text{StdDev} (\sigma) = \sqrt{\text{Variance}}$$ ### C. Z-Score 统计阈值 $$\text{Z-Score} = \frac{\text{Packet Size} - \text{Mean Size}}{\text{Standard Deviation}}$$ * **Z-Score 介于 -3.0 和 +3.0 之间:** 正常流量(根据高斯正态分布,**99.73%** 的所有标准数据都落在此范围内)。 * **Z-Score > 3.0:** 极端异常值!与当前网络趋势相比,该数据包大得异常。触发即时的 **`ALERT`** 日志。 ### D. 生产者-消费者模式与背压 ### 🚗 简单类比(机场货物检查) 想象一个繁忙的国际机场,每分钟都有成千上万的行李箱到达: * **没有我们的系统(旧方法):** 一名保安站在机舱门口。他接过一个行李箱,打开它,进行测量,将其重量与今天到达的所有行李箱进行对比计算,并写下一份报告。与此同时,另外 100 架飞机正在空中盘旋等待,因为保安太慢了。行李箱都弄丢了! * **使用我们的系统(我们的设计):** * **接收保安(生产者):** 站在机舱门口。他只需在每个行李箱上贴上一张便利贴(IP 地址、大小、时间戳),然后将其扔到传送带(`ThreadSafeQueue`)上。他一刻也不停歇! * **分析保安(消费者):** 站在传送带的尽头。他阅读便利贴,在一块小白板上更新他的连续计数器,并立即将行李箱从传送带上清空。如果突然出现一个重达 500 公斤的巨大行李箱,他就会吹响警哨(异常警报!)。 ### 📊 简明数学原理 #### 1. 什么是 Welford's Algorithm? 传统上,要计算数字的平均值和方差,您必须将所有过去的数字记在笔记本上,并且每次新数字到来时都要对它们重新求和。 **Welford's Algorithm** 允许我们仅使用存储在内存中的 **3 个数字** 来逐步计算精确的连续平均值($\mu$)和方差($\sigma^2$): $$\mu_k = \mu_{k-1} + \frac{x_k - \mu_{k-1}}{k}$$ $$M_{2,k} = M_{2,k-1} + (x_k - \mu_{k-1})(x_k - \mu_k)$$ * $x_k$:新到达的数据包的大小。 * $\mu_k$:更新后的连续平均值。 * $M_2$:差的平方的累计总和(用于计算方差 $\sigma^2 = \frac{M_2}{k-1}$)。 #### 2. 什么是 Z-Score? **Z-Score** 衡量特定数据包的大小偏离正常平均流量大小的“标准差”个数: $$Z = \frac{x - \mu}{\sigma}$$ * 根据高斯分布原理,**99.73%** 的正常网络流量落在 $-3.0$ 和 $+3.0$ 之间的 Z-Score 范围内。 * 如果到达的数据包的 **$Z > 3.0$**,则它是正常流量的概率不到 **0.27%**。引擎会立即将其标记为**异常警报**。 ## 🛠️ 6. 构建与运行项目 ### 前置条件 (Ubuntu / Linux) * **操作系统:** Linux(推荐使用 Ubuntu 22.04 / 24.04 LTS) * **编译器:** GCC `g++`(支持 C++17 的 v13+ 版本) * **构建系统:** `CMake` (v3.14+) * **依赖项:** `libpcap-dev` ``` # 在 Ubuntu/Debian 上安装依赖 sudo apt update sudo apt install -y build-essential cmake libpcap-dev ``` ### 编译项目 ``` # 1. 克隆或导航到 repository cd NetworkAnalyzer # 2. 创建 build 目录 mkdir build && cd build # 3. 生成 build 文件并编译 cmake .. make -j$(nproc) ``` ### 运行自动化测试套件 (CTest) ``` ctest --output-on-failure ``` ### 运行分析器 注意:捕获原始网络数据包需要 root 或原始 socket 权限 (sudo)。 ``` # 在默认接口上运行 (eth0) sudo ./NetworkAnalyzer # 或者指定一个目标接口 (例如, wlan0) sudo ./NetworkAnalyzer wlan0 ``` ## 🧪 7. 运行自动化测试套件 该项目包含一个通过 `CTest` 集成的测试套件。所有单元测试和集成**测试均验证了线程安全性**、**数学精度**以及**边缘情况**。 要同时执行所有测试: ``` cd build ctest --output-on-failure ``` #### 单独测试功能: - `test_packet_ingestor`:验证对数据包大小和请求头偏移量的正确解析。 - `test_thread_safe_queue`:在高负载下运行并发的多线程 push/pop 操作,以测试数据竞争和死锁。 - `test_anomaly_detector`:验证 Welford's algorithm 的收敛性、标准差的准确性以及 Z-Score 的触发。 - `test_integration_pipeline`:验证从接收数据到记录异常的端到端多线程数据流。 ## ⚡ 8. 性能与线程安全保证 | 指标 / 功能 | 保证与实现细节 | | :--- | :--- | | **语言标准** | C++17,使用严格标志编译(`-Wall -Wextra -Wpedantic -Werror -O3`) | | **内存复杂度** | 通过 Welford's Streaming Algorithm 实现 $O(1)$ 恒定内存空间 | | **时间复杂度** | 每个数据包的分析处理时间为 $O(1)$ | **并发模式** | 使用 `std::thread` 的解耦生产者-消费者模式 | | **同步机制** | 使用 `std::mutex`、`std::unique_lock` 和 `std::condition_variable` 进行保护 | | **数据竞争安全** | 零数据竞争(通过 ThreadSanitizer 和 RAII 锁验证) | | **内存管理** | "100% 符合 RAII(`std::unique_ptr`,零原始内存分配))" | | **关闭保护** | 优雅关闭(`SIGINT`/`SIGTERM`)并自动进行资源清理 | ## 🏛️ 9. 实现的关键 C++17 工程概念 * **RAII(资源获取即初始化):** 将原始的 C 句柄(`pcap_t*`)封装到 C++ 对象中,确保在析构时进行干净的清理。 * **并发原语:** 使用 `std::mutex`、`std::unique_lock`、`std::lock_guard` 和 `std::condition_variable` 消除数据竞争和死锁。 * **背压管理:** 当达到容量上限时,有界的 `ThreadSafeQueue` 会阻塞生产者,以防止 Out-Of-Memory (OOM) 异常。 * **信号安全:** 拦截 POSIX 信号(`SIGINT`、`SIGTERM`)以触发优雅的拆卸过程和干净的线程汇合(join)。 * **移动语义 (`std::move`):** 跨线程传递元数据,实现零不必要的堆内存分配。 ## 👩‍💻 10. 作者与许可证 * **由 `Yara Hneif (2026)` 设计与工程开发。** * **领域:`计算机科学` / `高性能系统编程`。** * **许可证:基于 MIT 许可证分发。专为高性能系统工程和网络安全运营而开发。**
标签:Bash脚本, C++17, HTTP头分析, Welford算法, 多线程并发, 异常检测, 网络流量分析