Sergeb250/packetEye
GitHub: Sergeb250/packetEye
packetEye 是一个 AI 驱动的网络取证与威胁狩猎平台,通过解析 PCAP 文件并结合威胁情报、规则检测、ML 异常评分与 LLM 自动生成分析报告,帮助分析师高效发现和解释网络流量中的可疑行为。
Stars: 0 | Forks: 0
# packetEye
**AI 驱动的网络取证与威胁狩猎平台**
packetEye 接收 PCAP/CAP 网络抓包文件,重构每一个网络流,通过威胁情报丰富可观察对象,运行 17 条检测规则以及 ML 异常评分,并使用 **NVIDIA NIM (DeepSeek V4)** 生成通俗易懂的分析师叙述、执行摘要和狩猎假设。
## 目录
1. [packetEye 的功能](#1-what-packeye-does)
2. [系统架构](#2-system-architecture)
3. [技术栈](#3-technology-stack)
4. [目录结构](#4-directory-structure)
5. [应用引导](#5-application-bootstrap)
6. [数据库模型](#6-database-models)
7. [分析流水线 (Celery 任务)](#7-analysis-pipeline-celery-tasks)
8. [PCAP 解析器](#8-pcap-parser)
9. [富化层](#9-enrichment-layer)
10. [检测引擎](#10-detection-engine)
11. [ML 异常引擎](#11-ml-anomaly-engine)
12. [LLM 层 (NVIDIA NIM / DeepSeek V4)](#12-llm-layer-nvidia-nim--deepseek-v4)
13. [报告生成器](#13-report-builder)
14. [Web UI 与 REST API](#14-web-ui--rest-api)
15. [白名单引擎](#15-whitelist-engine)
16. [配置参考](#16-configuration-reference)
17. [快速开始](#17-quick-start)
18. [安全说明](#18-security-notes)
## 1. packetEye 的功能
当分析师上传一个 PCAP 文件时:
1. **解析** — 重构五元组流(源 IP、目的 IP、端口、协议),并提取 DNS 查询、HTTP 主机、TLS SNI、JA3 哈希、ARP 事件。
2. **富化** — 为每个唯一的 IP/域名扇出请求到 VirusTotal、AbuseIPDB、WHOIS 和 ip-api(缓存在 Redis 中)。
3. **检测** — 评估 17 条 YAML 定义的规则(端口扫描、Beaconing、DNS 隧道等),并使用 Isolation Forest ML 对流进行评分。
4. **分析 (LLM)** — 通过 NVIDIA 免费的 NIM API 调用 **DeepSeek V4 Pro** 来解释发现、编写执行摘要并提出狩猎假设。
5. **报告** — 组装指标、图表、地理地图数据和导出格式(HTML、JSON、STIX2、CSV)。
前端每 3 秒轮询一次 `/api/analysis//status`,并显示实时进度条。
## 2. 系统架构
```
flowchart TB
subgraph Client
Browser[Bootstrap 5 UI]
end
subgraph Flask["Flask Application"]
MainRoutes[main.py — pages]
APIRoutes[api.py — REST]
Models[(SQLAlchemy Models)]
end
subgraph Workers["Celery Workers"]
T1[parse_pcap]
T2[enrich_observables]
T3[run_detections]
T4[run_llm_analysis]
T5[build_report]
end
subgraph Services
Parser[pcap_parser.py]
Enrich[enrichment/orchestrator.py]
Detect[detection/engine.py]
ML[detection/ml_engine.py]
LLM[llm/analyst.py]
Report[report_builder.py]
end
subgraph External
Redis[(Redis)]
SQLite[(SQLite / PostgreSQL)]
NVIDIA[NVIDIA NIM API\nDeepSeek V4]
VT[VirusTotal]
AIPDB[AbuseIPDB]
Geo[ip-api]
end
Browser -->|POST /api/upload| APIRoutes
Browser -->|poll status| APIRoutes
APIRoutes --> Models
APIRoutes -->|enqueue| T1
T1 --> Parser --> Models
T1 --> T2
T2 --> Enrich --> VT & AIPDB & Geo
Enrich --> Redis
T2 --> T3
T3 --> Detect & ML --> Models
T3 --> T4
T4 --> LLM --> NVIDIA
T4 --> T5
T5 --> Report --> Models
Models --> SQLite
```
### 设计原则
| 原则 | 实现 |
|-----------|----------------|
| **异步流水线** | 耗时任务绝不会阻塞 Flask 请求线程;Celery 任务按顺序链式执行。 |
| **进度可见性** | 每个任务都会更新数据库中的 `Analysis.status` 和 `Analysis.progress_pct`。 |
| **可插拔的 LLM** | `LLMProvider` 抽象支持 NVIDIA(默认)、OpenAI、Anthropic。 |
| **可选的富化** | 缺失 API key 会跳过该提供商;流水线仍会完成执行。 |
| **规则驱动的检测** | 新的检测 = 在 `detection_rules/` 中添加新的 YAML 文件 — 参数无需更改代码。 |
## 3. 技术栈
| 层级 | 技术 | 角色 |
|-------|------------|------|
| 后端 | Python 3.11+、Flask | 应用工厂、路由、模板 |
| 任务队列 | Celery + Redis | 5 阶段分析流水线 |
| PCAP 解析 | `dpkt` | 快速的二进制数据包解析 |
| 数据库 | SQLite (开发) / PostgreSQL (生产) | 分析、流、发现 |
| 前端 | Bootstrap 5、Chart.js、Leaflet | 上传、仪表盘、报告 |
| **LLM (默认)** | **NVIDIA NIM + DeepSeek V4 Pro** | 位于 `integrate.api.nvidia.com` 的免费 API |
| ML | scikit-learn Isolation Forest | 无监督流异常评分 |
| 富化 | aiohttp + asyncio | 并发 API 扇出 |
## 4. 目录结构
```
packetEye/
├── app/
│ ├── __init__.py # create_app() — Flask factory
│ ├── config.py # Environment-based configuration classes
│ ├── extensions.py # db, cache, celery, limiter singletons
│ │
│ ├── models/
│ │ ├── analysis.py # Analysis, Flow, Observable, Finding
│ │ └── user.py # User (optional Flask-Login auth)
│ │
│ ├── routes/
│ │ ├── main.py # HTML pages: /, /dashboard, /report/
│ │ ├── api.py # REST JSON API under /api/*
│ │ └── auth.py # Login/logout (optional)
│ │
│ ├── services/
│ │ ├── pcap_parser.py # PCAP → flows + observables
│ │ ├── enrichment/ # Threat intel API clients
│ │ ├── detection/ # Rules + ML + scoring
│ │ ├── llm/ # NVIDIA/OpenAI/Anthropic providers
│ │ └── report_builder.py # Final report JSON assembly
│ │
│ ├── tasks/
│ │ └── analysis_tasks.py # Celery task chain definitions
│ │
│ ├── templates/ # Jinja2 HTML (Bootstrap 5)
│ └── static/ # CSS, JavaScript
│
├── detection_rules/ # YAML rule definitions (17 rules)
├── whitelist/ # Known-good CIDRs/domains
├── tests/ # pytest unit tests
├── .env # Local secrets (gitignored)
├── .env.example # Template for configuration
├── run.py # `python run.py` → Flask dev server
└── celery_worker.py # Celery worker entry point
```
## 5. 应用引导
### `app/__init__.py` — `create_app()`
这是**应用工厂**。它会:
1. 通过 `python-dotenv` 加载 `.env`
2. 选择配置类(`DevelopmentConfig`、`ProductionConfig`、`TestingConfig`)
3. 初始化扩展:`db`、`cache`、`login_manager`、`limiter`、`celery`
4. 注册蓝图:`main_bp`、`api_bp`、`auth_bp`
5. 使用 `db.create_all()` 创建数据库表
6. 导入 Celery 任务,以便它们在 worker 中注册
### `app/config.py`
| 类 | 用途 |
|-------|---------|
| `Config` | 来自环境变量的基础设置 |
| `DevelopmentConfig` | `DEBUG=True`、`SimpleCache`、`CELERY_TASK_ALWAYS_EAGER=True`(无需 Redis) |
| `ProductionConfig` | 生产环境标志 |
| `TestingConfig` | 内存中的 SQLite,禁用 LLM |
LLM 的关键默认配置:
```
LLM_PROVIDER = "nvidia"
LLM_MODEL = "deepseek-ai/deepseek-v4-pro"
NVIDIA_API_BASE = "https://integrate.api.nvidia.com/v1"
```
### `app/extensions.py`
| 对象 | 库 | 用途 |
|--------|---------|---------|
| `db` | Flask-SQLAlchemy | ORM 和数据库迁移 |
| `cache` | Flask-Caching | 富化 + LLM 响应缓存 |
| `celery_app` | Celery | 异步任务代理 |
| `limiter` | Flask-Limiter | 上传速率限制(10次/小时) |
| `login_manager` | Flask-Login | 可选的身份验证 |
`init_celery(app, celery_app)` 将每个 Celery 任务包装在 Flask 应用上下文中,以便 `db.session` 能在 worker 内部正常工作。
## 6. 数据库模型
所有模型都位于 `app/models/analysis.py` 中。
### `Analysis`
代表一个已上传的 PCAP 文件及其流水线状态。
| 字段 | 类型 | 含义 |
|-------|------|---------|
| `id` | UUID 字符串 | 主键,上传后返回给客户端 |
| `filename` | str | 原始上传文件名 |
| `file_path` | str | 磁盘上基于 UUID 的存储路径 |
| `status` | 枚举字符串 | `queued` → `parsing` → `enriching` → `analyzing` → `complete` / `failed` |
| `progress_pct` | int 0–100 | 前端进度条数值 |
| `risk_score` | float 0–10 | 根据发现结果计算的综合严重程度 |
| `summary_json` | JSON | 仪表盘统计数据、执行摘要文本 |
| `report_json` | JSON | 供 UI/导出使用的完整组装报告 |
**方法:** `to_dict()` — 序列化以用于 REST API 响应。
### `Flow`
一个重构的网络流(五元组 + 统计信息 + 产出物)。
| 字段组 | 示例 |
|-------------|----------|
| 身份标识 | `src_ip`、`dst_ip`、`src_port`、`dst_port`、`protocol` |
| 统计信息 | `bytes_sent`、`bytes_recv`、`duration_ms`、`packets_sent` |
| 产出物 | `dns_queries`、`http_hosts`、`tls_sni`、`ja3_hash`、`user_agents` |
| 评分 | `anomaly_score`、`severity_score`、`rule_flags`、`is_whitelisted` |
| 富化 | `enrichment_json` — 合并后的提供商结果 |
### `Observable`
从流量中提取的唯一指标(每次分析进行去重)。
| 字段 | 含义 |
|-------|---------|
| `type` | `ip`、`domain`、`ja3`、`cert_hash`、`url`、`user_agent` |
| `value` | 指标字符串 |
| `enrichment_status` | `pending`、`complete`、`error`、`cached` |
| `is_malicious` | 来自所有提供商的统一判定 |
| `confidence` | 0.0–1.0 的置信度评分 |
### `Finding`
安全检测结果(来自规则、ML 或 LLM)。
| 字段 | 含义 |
|-------|---------|
| `rule_id` | 例如 `BEACON-001`、`ML-ANOMALY-001` |
| `source` | `rule`、`ml`、`llm`、`ti_correlation` |
| `severity` | `critical`、`high`、`medium`、`low`、`info` |
| `evidence` | 包含触发规则的流、IP、统计信息的 JSON |
| `mitre_tactic` / `mitre_technique` | ATT&CK 映射 |
| `llm_explanation` | DeepSeek 生成的通俗易懂的文本 |
| `recommendation` | 具有指导意义的分析师下一步行动建议 |
| `is_false_positive` | 通过分析师反馈 API 进行设置 |
## 7. 分析流水线 (Celery 任务)
定义在 `app/tasks/analysis_tasks.py` 中。任务会自动链式调用 — 每个任务都会对下一个任务调用 `.delay()`。
### 进度映射
| 阶段 | 任务 | 进度 % | 具体操作 |
|-------|------|------------|--------------|
| 1 | `parse_pcap` | 0 → 25 | 读取 PCAP,创建 Flow + Observable 行 |
| 2 | `enrich_observables` | 25 → 55 | 为每个 observable 进行异步 API 扇出请求 |
| 3 | `run_detections` | 55 → 70 | YAML 规则 + Isolation Forest |
| 4 | `run_llm_analysis` | 70 → 90 | DeepSeek 富化发现结果 |
| 5 | `build_report` | 90 → 100 | 执行摘要、假设、报告 JSON |
### 函数参考
#### `run_analysis(analysis_id)`
从 `/api/upload` 调用的入口点。分派 `parse_pcap.delay(analysis_id)`。
#### `parse_pcap(analysis_id)`
- 实例化 `PCAPParser(file_path)`
- 调用 `parser.parse(progress_callback=...)` — 流式处理数据包,构建流
- 将 `Flow` 和 `Observable` 行插入数据库
- 设置 `analysis.total_flows`
- 链式调用至 `enrich_observables`
#### `enrich_observables(analysis_id, arp_events)`
- 使用应用配置创建 `EnrichmentOrchestrator`
- 运行 `enrich_analysis_sync()` — worker 内部的 asyncio 事件循环
- 更新每个 `Observable.enrichment_json`、`is_malicious`、`confidence`
- 链式调用至 `run_detections`
#### `run_detections(analysis_id, arp_events)`
- 从数据库加载所有流和可观察对象
- 运行 `DetectionEngine.run()` — 返回 `Finding` 对象列表
- 保存发现,更新流异常评分 `anomaly_score`
- 链式调用至 `run_llm_analysis`
#### `run_llm_analysis(analysis_id)`
- 创建 `LLMAnalyst` → 对中等及以上严重程度的发现调用 `enrich_findings()`
- 链式调用至 `build_report`(即使 LLM 失败也会执行)
#### `build_report(analysis_id)`
- `LLMAnalyst.generate_executive_summary()` — 一次 DeepSeek 调用
- `LLMAnalyst.generate_hunt_hypotheses()` — 一次 DeepSeek 调用
- `ReportBuilder.build()` — 组装图表、指标、地理标记
- 设置 `status=complete`、`progress_pct=100`、`completed_at`
#### `_update_progress(analysis_id, status, pct)`
用于向数据库提交 `Analysis.status` 和 `Analysis.progress_pct` 的辅助方法。
## 8. PCAP 解析器
**文件:** `app/services/pcap_parser.py`
### 类:`PCAPParser`
#### `__init__(file_path)`
存储路径并初始化空的 `flows`、`arp_events`、`observables` 字典。
#### `parse(progress_callback=None) → dict`
主入口点:
1. 检测 PCAP 与 PCAPNG 的魔数
2. 使用 `dpkt.pcap.Reader` 或 `dpkt.pcapng.Reader` 遍历数据包
3. 为每个数据包调用 `_process_packet(ts, buf)`
4. 返回 `{"flows": [...], "observables": [...], "arp_events": [...]}`
#### `_process_packet(ts, buf)`
- 解析以太网帧
- 处理 ARP → 追加到 `arp_events`
- 处理 IP → 分派 TCP、UDP 或 ICMP
- 为每个五元组创建/更新 `FlowState` 数据类
#### `_inspect_tcp_payload(flow, tcp, ...)`
提取应用层数据:
- **TLS/443:** 通过 `_extract_sni()` 获取 SNI,通过 `_compute_ja3()` 计算 JA3
- **HTTP/80:** 从 `dpkt.http.Request` 获取 Host 标头和 User-Agent
- **SSH/445/3389:** 设置 `application_layer` 标签
#### `_inspect_udp_payload(flow, udp, ...)`
- 端口 53 → 解析 `dpkt.dns.DNS`,提取查询名称
#### `_track_observable(type, value, ts)`
对可观察对象进行去重;增加 `occurrence_count`。
### 辅助函数
| 函数 | 用途 |
|----------|---------|
| `validate_pcap_magic(file_path)` | 服务端文件验证(不仅仅基于扩展名) |
| `is_private_ip(ip)` / `is_external_ip(ip)` | 用于检测规则的 RFC1918 检查 |
| `_extract_sni(data)` | 手动解析 TLS ClientHello SNI |
| `_compute_ja3(tls)` | 密码/扩展字符串的 MD5 哈希 |
### `FlowState` 数据类
插入数据库前的内存流累加器 — 保存数据包时间、DNS 集合、HTTP 主机、TLS 字段。
## 9. 富化层
**编排器:** `app/services/enrichment/orchestrator.py`
### 类:`EnrichmentOrchestrator`
#### 路由逻辑
| Observable 类型 | 被调用的提供商 |
|-----------------|------------------|
| `ip` | VirusTotal、AbuseIPDB、地理位置 (ip-api)、WHOIS (rDNS) |
| `domain` | VirusTotal、WHOIS |
#### 关键方法
| 方法 | 描述 |
|--------|-------------|
| `_cache_key(provider, type, value)` | Redis 键:`enrich:{provider}:{type}:{hash}` |
| `_get_cached` / `_set_cache` | 24 小时 TTL(可配置) |
| `_enrich_ip(ip)` | 并发异步调用所有 IP 提供商 |
| `_enrich_domain(domain)` | VT + WHOIS |
| `_compute_verdict(enrichment)` | 合并提供商信号 → `is_malicious`、`confidence` |
| `enrich_observable(obs)` | 单个 observable 富化 |
| `enrich_all(analysis_id)` | 对所有 observable 进行由信号量限制的并行富化 |
| `enrich_analysis_sync(analysis_id)` | 用于 Celery 的 `asyncio.run()` 包装器 |
#### 判定阈值
| 提供商 | 标记条件 |
|----------|----------------|
| VirusTotal | `malicious > 2` |
| AbuseIPDB | `abuseConfidenceScore > 25` |
| WHOIS | 域名注册时间 < 30 天 |
### 提供商模块
| 文件 | 类 | API |
|------|-------|-----|
| `virustotal.py` | `VirusTotalClient` | VT v3 REST,令牌桶算法限制为 4 请求/分钟 |
| `abuseipdb.py` | `AbuseIPDBClient` | AbuseIPDB v2 检查 |
| `whois_lookup.py` | `WhoisClient` | `python-whois` + `socket.gethostbyaddr` |
| `geo_asn.py` | `GeoASNClient` | ip-api.com(免费)或 MaxMind GeoLite2 |
## 10. 检测引擎
**文件:** `app/services/detection/engine.py`
### 类:`DetectionEngine`
#### `__init__(config)`
- 通过 `load_rules(DETECTION_RULES_DIR)` 加载 YAML 规则
- 初始化 `WhitelistEngine`
- 初始化带有阈值和模型路径的 `MLEngine`
#### `run(analysis_id, flows, arp_events, observables) → list[Finding]`
1. 标记白名单流(`is_whitelisted=True`)
2. 针对非白名单流评估每条 YAML 规则
3. 对所有活跃流运行 ML 评分
4. 返回合并后的 `Finding` 对象列表(尚未提交)
#### `_evaluate_rule(rule, flows, arp_events, observables)`
根据 `rule["id"]` 分派给相应的处理程序:
| 规则 ID | 处理程序 | 逻辑摘要 |
|---------|---------|---------------|
| `PORTSCAN-001` | `_portscan_horizontal` | 30秒内同一目的 IP 有 >50 个端口被扫描 |
| `PORTSCAN-002` | `_portscan_vertical` | 60秒内同一端口有 >30 个目的 IP 被扫描 |
| `BEACON-001` | `_beacon` | 规律的时间间隔,变异系数 (CV) < 20% |
| `BEACON-002` | `_beacon_slow` | Beacon 间隔 > 30 分钟 |
| `DNSTUNNEL-001` | `_dns_payload` | DNS 载荷 > 200 字节 |
| `DNSTUNNEL-002` | `_dns_frequency` | 对顶级域名每分钟查询 >100 次 |
| `DNSTUNNEL-003` | `_dns_entropy` | 子域名熵 > 3.8 |
| `ARPSPOOFING-001` | `_arp_gratuitous` | 无故(Gratuitous) ARP 事件 |
| `ARPSPOOFING-002` | `_arp_storm` | 10秒内出现 >50 个 ARP 回复 |
| `PORTMISMATCH-001` | `_port_mismatch` | 在错误端口上的 SSH/HTTP/DNS 通信 |
| `EXFIL-001` | `_exfil` | 出站字节数 > 基准的 10 倍 |
| `LATERAL-001` | `_lateral` | 在 445/3389/5985 端口上的内部扫描 |
| `DGATOP-001` | `_dga` | 高辅音/元音比例或二元语法熵 |
| `TLSNONSNI-001` | `_tls_no_sni` | 到外部 IP 的 TLS 连接没有 SNI |
| `CLEARTEXT-001` | `_cleartext` | 发往认证接口的明文 HTTP POST 请求 |
| `NEWDOMAIN-001` | `_new_domain` | WHOIS 注册时间 < 30 天 |
| `LONGCONN-001` | `_long_conn` | TCP 流持续时间 > 8 小时 |
### 规则 YAML 格式(`detection_rules/*.yaml`)
```
- id: BEACON-001
name: Beaconing — periodic outbound connection
description: >
Repeated connections at regular intervals indicating C2 check-in.
severity: high
enabled: true
mitre_tactic: TA0011 - Command and Control
mitre_technique: T1071 - Application Layer Protocol
parameters:
min_connections: 10
max_jitter_pct: 20
recommendation: >
Isolate the source host and examine the destination certificate.
```
规则由 `app/services/detection/rules.py` 的 `load_rules()` 加载,该函数会读取所有 `*.yaml` 文件并过滤掉 `enabled: false` 的规则。
### 评分 (`scoring.py`)
| 函数 | 用途 |
|----------|---------|
| `severity_to_score(severity)` | 将 critical 映射为 10,high 映射为 8,medium 映射为 5 等 |
| `compute_analysis_risk_score(findings)` | 取前 5 个发现的平均值,上限为 10 |
## 11. ML 异常引擎
**文件:** `app/services/detection/ml_engine.py`
### 算法:Isolation Forest (scikit-learn)
无监督算法 — 无需标记的恶意软件数据。在特征空间中“容易被孤立”的流即为异常。
### 特征向量(11 维)
| 特征 | 转换 |
|---------|-----------|
| `bytes_total_log` | log1p(发送字节数 + 接收字节数) |
| `packets_total` | 原始计数 |
| `duration_ms_log` | log1p(持续时间) |
| `bytes_per_packet` | 字节数 / 数据包数 |
| `iat_mean`、`iat_std` | 到达时间间隔统计 |
| `dst_port` | 原始端口号 |
| `dst_port_entropy` | 源 IP 访问端口的熵 |
| `is_external_dst` | 如果目的 IP 不属于 RFC1918 则为 1 |
| `time_of_day_hour` | 0–23 |
| `protocol_encoded` | TCP=1、UDP=2、ICMP=3 |
### 类:`MLEngine`
| 方法 | 描述 |
|--------|-------------|
| `score_flows(flows)` | 构建特征矩阵,运行 Isolation Forest,返回分数 + 解释 |
| `_simple_explanations(features_df, scores)` | 文本:“因异常的 {feature} 被标记” |
### 训练模式
1. **无基准模型** — 在抓包数据的前 80% 的流上拟合 Isolation Forest
2. **预训练** — 如果存在 `ml_models/isolation_forest_base.pkl`,则直接加载
通过 `normalize_if_score()` 将分数从 Isolation Forest 的范围 (-1, 0) 归一化到 **0–10**。分数高于 `ML_ANOMALY_THRESHOLD`(默认为 7.5)的流会创建一个 `source='ml'` 的 `Finding`。
## 12. LLM 层 (NVIDIA NIM / DeepSeek V4)
**默认提供商:** NVIDIA 免费的 NIM API,采用 **DeepSeek V4 Pro**。
在 [build.nvidia.com](https://build.nvidia.com) 获取免费的 API key → 复制 `nvapi-...` key。
### 架构
```
LLMAnalyst (analyst.py)
└── get_provider(config) → NVIDIAProvider | OpenAIProvider | AnthropicProvider
└── complete(system, user, temperature) → raw text
└── parse_json_response() → dict
└── complete_with_retry() → up to 3 attempts
```
### `app/services/llm/provider.py`
#### `NVIDIAProvider` (默认)
使用指向 NVIDIA endpoint 的 **OpenAI Python SDK**:
```
client = OpenAI(
base_url="https://integrate.api.nvidia.com/v1",
api_key=os.environ["NVIDIA_API_KEY"],
)
response = client.chat.completions.create(
model="deepseek-ai/deepseek-v4-pro",
messages=[{"role": "system", ...}, {"role": "user", ...}],
extra_body={"chat_template_kwargs": {"thinking": False}}, # reliable JSON
)
```
| 模型 | 用例 |
|-------|----------|
| `deepseek-ai/deepseek-v4-pro` | 最佳质量(默认) — 发现分析、摘要 |
| `deepseek-ai/deepseek-v4-flash` | 更快,更低延迟 — 大批量或开发环境 |
#### 其他提供商
| 类 | 使用时机 |
|-------|-------------|
| `OpenAIProvider` | 设置 `LLM_PROVIDER=openai`、`LLM_API_KEY=sk-...` |
| `AnthropicProvider` | 设置 `LLM_PROVIDER=anthropic` |
#### 实用功能
| 函数 | 用途 |
|----------|---------|
| `get_provider(config)` | 工厂方法 — 读取 `LLM_PROVIDER` 环境变量 |
| `parse_json_response(text)` | 从 LLM 输出中提取 JSON(处理 markdown 围栏) |
| `complete_with_retry(...)` | 指数退避,最多重试 3 次 |
### `app/services/llm/analyst.py` — `LLMAnalyst`
| 方法 | 温度 | 输出 |
|--------|-------------|--------|
| `enrich_findings(analysis_id)` | 0.2 | 每个发现的 JSON:解释、建议、置信度 |
| `generate_executive_summary(analysis_id)` | 0.3 | 3-5 段面向利益相关者的摘要 |
| `generate_hunt_hypotheses(analysis_id)` | 0.5 | 3-5 个包含步骤的调查假设 |
**成本控制:** `_call_count` 最多为 `LLM_MAX_CALLS_PER_ANALYSIS`(默认为 25)。响应通过输入的 SHA256 缓存在 Redis 中 — 重新加载时绝不重新查询。
### `app/services/llm/prompts.py`
模板字符串:`SYSTEM_ANALYST`、`FINDING_PROMPT`、`EXECUTIVE_SUMMARY_PROMPT`、`HUNT_HYPOTHESES_PROMPT`。
LLM **绝不会接收原始的数据包字节** — 仅接收结构化的 JSON 元数据(流统计信息、富化判定、MITRE 上下文)。
## 13. 报告生成器
**文件:** `app/services/report_builder.py`
### 类:`ReportBuilder`
#### `build(analysis_id, executive_summary, hunt_hypotheses) → dict`
组装存储在 `Analysis.report_json` 中的最终报告对象:
| 部分 | 内容 |
|---------|----------|
| `analysis` | 通过 `to_dict()` 获取的分析元数据 |
| `executive_summary` | DeepSeek 生成的文本 |
| `hunt_hypotheses` | 假设卡片列表 |
| `risk_score` | 来自 `compute_analysis_risk_score()` |
| `metrics` | 流计数、外部 IP、恶意 IOC、严重程度分布 |
| `charts` | 协议饼图、主要通信者、流量时间轴、DNS 热门域名、端口热力图 |
| `geo_markers` | 来自 ip-api 富化的经纬度,用于 Leaflet 地图 |
## 14. Web UI 与 REST API
### HTML 页面 (`app/routes/main.py`)
| 路由 | 模板 | 用途 |
|-------|----------|---------|
| `GET /` | `index.html` | 拖拽上传 PCAP |
| `GET /dashboard` | `dashboard.html` | 分析历史记录表 |
|GET /analysis/` | `analysis_progress.html` | 实时进度条(轮询 API) |
| `GET /report/` | `report.html` | 完整的 8 部分报告 |
### JavaScript
| 文件 | 角色 |
|------|------|
| `static/js/upload.js` | 客户端验证,`POST /api/upload`,重定向至进度页 |
| `static/js/report.js` | Leaflet 威胁地图,误报反馈 |
| `static/js/charts.js` | Chart.js:风险仪表盘、协议饼图、通信者、时间轴 |
### REST API (`app/routes/api.py`)
| 方法 | 端点 | 功能 |
|--------|----------|----------|
| POST | `/api/upload` | `upload()` — 验证 PCAP,保存文件,将 `run_analysis` 加入队列 |
| GET | `/api/analysis//status` | `analysis_status()` — 轮询进度 |
| GET | `/api/analysis//summary` | 主要统计信息 + 报告 |
| GET | `/api/analysis//findings` | 可过滤的发现结果列表 |
| GET | `/api/analysis//flows` | 分页流表格 |
| GET | `/api/analysis//observables` | 已富化的 IOC |
| GET | `/api/analysis//report.json` | 完整报告 JSON |
| GET | `/api/analysis//report.html` | 独立的 HTML 导出 |
| GET | `/api/analysis//stix2.json` | STIX2 包 |
| GET | `/api/analysis//export.csv` | 流 CSV 下载 |
| DELETE | `/api/analysis/` | 删除分析记录 + PCAP 文件 |
| POST | `/api/analysis//feedback` | 标记发现为误报 |
| GET | `/api/health` | 健康状态 + API key 状态 |
## 15. 白名单引擎
**文件:** `detection_rules/../whitelist/default_whitelist.yaml`
**类:** `detection/engine.py` 中的 `WhitelistEngine`
将已知良好的流量从发现结果中排除:
| 规则类型 | 示例 |
|-----------|---------|
| CIDR 范围 | Cloudflare、Google DNS、CloudFront |
| 域名模式 | `*.google.com`、`windowsupdate.microsoft.com` |
| 端口/协议 | UDP/53、TCP/443、TCP/80 |
`is_whitelisted_flow(flow_dict)` 会将 `Flow.is_whitelisted` 设置为 `True`;白名单流会跳过规则评估。
## 16. 配置参考
将 `.env.example` 复制到 `.env`:
```
# NVIDIA NIM — 默认 LLM(在 build.nvidia.com 免费)
LLM_PROVIDER=nvidia
NVIDIA_API_KEY=nvapi-your-key-here
NVIDIA_API_BASE=https://integrate.api.nvidia.com/v1
LLM_MODEL=deepseek-ai/deepseek-v4-pro
LLM_MAX_TOKENS=2048
LLM_MAX_CALLS_PER_ANALYSIS=25
LLM_ENABLED=true
# 可选的 enrichment
VIRUSTOTAL_API_KEY=
ABUSEIPDB_API_KEY=
# 数据库
DATABASE_URL=sqlite:///packeteye.db
# Dev mode(无 Redis)
CELERY_TASK_ALWAYS_EAGER=true
CACHE_TYPE=SimpleCache
```
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `LLM_PROVIDER` | `nvidia` | `nvidia`、`openai` 或 `anthropic` |
| `NVIDIA_API_KEY` | — | 来自 build.nvidia.com 的 `nvapi-...` |
| `LLM_MODEL` | `deepseek-ai/deepseek-v4-pro` | 或 `deepseek-ai/deepseek-v4-flash` |
| `ML_ANOMALY_THRESHOLD` | `7.5` | 评分高于此值的流会生成 ML 发现 |
| `MAX_UPLOAD_MB` | `500` | 上传大小限制 |
| `WHITELIST_ENABLED` | `true` | 开启/关闭白名单过滤 |
## 17. 快速开始
```
cd packetEye
python -m venv venv
.\venv\Scripts\activate
pip install -r requirements.txt
copy .env.example .env
# 编辑 .env — 添加来自 build.nvidia.com 的 NVIDIA_API_KEY
python run.py
```
打开 **http://localhost:5000**,上传 `.pcap` 文件,查看进度,浏览报告。
### 生产环境 (使用 Redis + Celery worker)
```
# Terminal 1
python run.py
# Terminal 2
celery -A celery_worker.celery_app worker --loglevel=info
```
### 运行测试
```
pytest tests/ -v
```
## 18. 安全说明
- **切勿提交 `.env`** — 它已被列入 `.gitignore`。API key 只能存在于环境变量中。
- **轮换暴露的密钥** — 如果密钥在聊天或日志中泄露,请在 build.nvidia.com 重新生成。
- PCAP 文件可能包含凭据 — 以受限权限存储在 `data/uploads/` 下。
- 通过 Flask-Limiter 限制每个 IP 每小时的上传次数为 10 次。
- LLM **仅接收元数据** — 绝不会接收原始数据包载荷。
- 模板中的 Observable 值会进行 HTML 转义,以防止恶意域名引发 XSS。
**packetEye v1.0** — HackingBay Rwanda | 网络安全部门
标签:DLL 劫持, IP 地址批量处理, 人工智能, 大语言模型, 搜索引擎查询, 用户模式Hook绕过, 网络安全, 网络流量分析, 逆向工具, 隐私保护