Damien-Mrgnc/threat-hunting-api
GitHub: Damien-Mrgnc/threat-hunting-api
一个部署在 GCP 的生产级威胁狩猎平台,提供 ML 驱动的流量检测、威胁情报增强与全链路可观测性,填补从数据采集到实时响应的安全运维空白。
Stars: 1 | Forks: 0
# 威胁狩猎 API
一个部署在 Google Cloud Platform 上的生产级威胁狩猎平台。结合了安全的 REST API、SQL/Redis 性能优化、基于 ML 的入侵检测、威胁情报 enrichment、全面的可观测性栈,以及使用 Terraform 的基础设施即代码。
**数据集:** [UNSW-NB15](https://research.unsw.edu.au/projects/unsw-nb15-dataset) — 700,000 条带有攻击类别标签的真实网络事件(DoS、Exploits、Reconnaissance、Backdoors…)
## 架构
```
Internet (HTTPS)
│
▼
┌──────────────────────────────────────────────────────────┐
│ Cloud Load Balancer (Global HTTPS) │
│ │
│ / → Portal Cloud Run │
│ /api/* → API Cloud Run (autoscale 1-10) │
│ /interface/* → Portal Cloud Run (SPA) │
│ /grafana/* → Grafana Cloud Run │
│ /prometheus/*→ Prometheus Cloud Run │
└──────────────────────────────────────────────────────────┘
│
├── Cloud SQL PostgreSQL 15 (private VPC — 10.1.0.3)
├── Memorystore Redis 6 (private VPC — 10.4.0.3)
└── VPC Connector (Cloud Run ↔ private resources)
```
所有 Cloud Run 服务通过 **私有 VPC** 与 Cloud SQL 和 Redis 通信 — 数据库端口绝不会暴露到互联网。
## 技术栈
| 层级 | 技术 |
|------|------|
| **API** | Python 3.12, FastAPI, SQLAlchemy, Pydantic v2 |
| **认证** | JWT (python-jose), bcrypt, SlowAPI 速率限制 |
| **数据库** | PostgreSQL 15, B-Tree 索引, 物化视图 |
| **缓存** | Redis 6 (Google Memorystore) |
| **ML 检测** | scikit-learn RandomForestClassifier, joblib |
| **威胁情报** | AbuseIPDB API(IP 信誉,缓存 24 小时到 Redis) |
| **可观测性** | Prometheus, Grafana(性能 + 安全仪表板),自定义指标 |
| **CI/CD** | GitHub Actions — Bandit SAST, pip-audit, Trivy, Checkov, Cloud Run 部署 |
| **基础设施** | Terraform(IaC),GCP Cloud Run, Cloud SQL, VPC,Secret Manager |
| **容器** | Docker,Artifact Registry,多阶段构建 |
| **本地开发** | Docker Compose(API × 3 副本,Nginx,PostgreSQL,Redis,Grafana) |
## 安全
### CI/CD 安全门禁(GitHub Actions)
每一次推送与拉取请求在代码进入生产环境前都会运行四项自动化安全检查:
| 门禁 | 工具 | 检查内容 |
|------|------|----------|
| **SAST** | [Bandit](https://bandit.readthedocs.io/) | Python 代码中硬编码的密钥、注入漏洞、不安全函数 |
| **依赖项审计** | [pip-audit](https://pypi.org/project/pip-audit/) | 所有固定 Python 依赖中的已知 CVE |
| **容器扫描** | [Trivy](https://trivy.dev/) | Docker 镜像中的 CVE(操作系统包 + Python 层) |
| **IaC 扫描** | [Checkov](https://www.checkov.io/) | Terraform 配置错误(开放端口、缺少加密、权限过宽的 IAM) |
结果会上传为 SARIF 到 **GitHub Security 面板** 以便集中追踪。
### 云(GCP)
- **私有网络** — Cloud SQL 与 Redis 仅可在 VPC 内部访问
- **Secret Manager** — `DATABASE_URL`、`JWT_SECRET_KEY`、`REDIS_URL` 存储为 GCP 密钥,运行时注入 — 代码或环境文件中不包含凭据
- **最小权限 IAM** — 专用的服务账户,仅赋予所需角色
- **强制 HTTPS** — TLS 终止在负载均衡器层面
### 应用程序
- **JWT 认证** — 所有敏感端点均需要有效的承载令牌
- **速率限制** — 基于 IP 的节流(SlowAPI),防止暴力破解与 DDoS 攻击
- **SQL 注入预防** — 全局使用 SQLAlchemy 参数化查询
- **输入验证** — 所有请求体与查询参数均使用严格的 Pydantic v2 Schema
### 本地(Docker Compose)
- API、PostgreSQL、Redis 与 Adminizer 位于内部 Docker 网络,仅 Nginx(端口 80/443)暴露给主机
- API 以 3 个副本运行在 Nginx 后方,实现负载分发
## ML 威胁检测
使用 RandomForestClassifier 在 UNSW-NB15 数据集上进行训练,以实时将网络事件分类为 **正常(0)** 或 **攻击(1)**。
| 属性 | 值 |
|------|-----|
| 算法 | RandomForestClassifier(scikit-learn) |
| 特征 | 40 个数值流特征(字节、包数、TTL、抖动、TCP 标志…) |
| 训练集 | 从 UNSW-NB15 中抽取 100,000 条分层样本 |
| 典型 ROC-AUC | ~0.98 |
| 推理延迟 | < 5 ms 每事件 |
**训练模型(首次推送前必需):**
```
# 从项目根目录
pip install scikit-learn joblib pandas numpy
python ml/train.py
# → 将模型保存至 api/ml/model.pkl (~10 MB)
# → 提交 api/ml/model.pkl 以包含在 Docker 镜像中
```
**使用该端点:**
```
TOKEN=$(curl -s -X POST http://localhost/auth/token \
-d "username=admin&password=secret" | jq -r .access_token)
curl -X POST http://localhost/api/detect \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sport": 1390, "dsport": 53, "dur": 0.001,
"sbytes": 132, "dbytes": 164, "sttl": 31, "dttl": 29,
"Spkts": 2, "Dpkts": 2, "Sload": 500473.9, "Dload": 621800.9
}'
# → {"label": 0, "is_attack": false, "confidence": 0.97, "model_roc_auc": 0.98}
```
## 威胁情报
IP 地址会通过 [AbuseIPDB](https://www.abuseipdb.com/) 进行信誉增强。结果缓存于 Redis 中 24 小时,以保持在免费层级(每日 1,000 次检查)范围内。
**设置 API 密钥:**
```
# 添加到 infra/.env(本地)或 GCP Secret Manager(生产环境)
ABUSEIPDB_API_KEY=your_key_here
```
**查询 IP:**
```
curl http://localhost/api/detect/intel/1.2.3.4 \
-H "Authorization: Bearer $TOKEN"
# → {"ip": "1.2.3.4", "abuse_confidence_score": 100, "is_malicious": true,
# "total_reports": 847, "country_code": "CN", "cached": false}
```
## 性能结果
测试运行在 **Cloud Run Job** 上,同一 GCP 内部网络(约 2ms 基础延迟)。
所有阶段均使用 100 个不同的源 IP 以消除 Redis 缓存偏差。
### `/events/search` — 1,000 次请求,并发 50
| 阶段 | RPS | P50 | P95 | P99 | 相比基准 |
|------|-----|-----|-----|-----|----------|
| 🐢 基准(无索引) | 16 req/s | 3,033 ms | 3,896 ms | 5,231 ms | — |
| 🔧 仅 SQL 索引 | 60 req/s | 743 ms | 1,416 ms | 1,738 ms | **×3.8 RPS / ×4.1 P50** |
| 🚀 完整优化(+Redis) | 64 req/s | 697 ms | 1,327 ms | 1,671 ms | **×4.1 RPS / ×4.4 P50** |
**应用的优化:**
- 在 `(srcip, ts, proto)` 上建立 B-Tree 索引 — 消除 70 万行的全表顺序扫描
- 物化视图 `mv_network_stats_proto` — 预计算字节聚合
- Redis 缓存 — 重复查询响应时间低于 10ms
### 突发测试 — 10,000 个并发请求
| 端点 | RPS | 成功率 | 结果 |
|------|-----|--------|------|
| `GET /health`(轻量) | 451 req/s | **99.99%** | ✅ Cloud Run 自动扩缩验证通过 |
| `GET /events/top/attack-categories`(重量级 DB) | 16 req/s | **1.3%** | ⚠️ 预期 — `db-g1-small` 连接数上限为 25 |
## 项目结构
```
threat-hunting-api/
├── .github/
│ └── workflows/
│ ├── ci.yml # Security gates: Bandit · pip-audit · Trivy · Checkov
│ └── cd.yml # Deploy to Cloud Run on push to main
├── api/ # FastAPI application
│ ├── core/ # database, auth, redis, observability (Prometheus metrics)
│ ├── ml/ # model.pkl — pre-trained RandomForest (generate with ml/train.py)
│ ├── routers/ # events, reports, jobs, auth, system, detect (ML + threat intel)
│ ├── services/ # reporting, threat_intel (AbuseIPDB)
│ └── tests/ # integration tests
├── db/
│ ├── schema.sql # PostgreSQL schema + seed users
│ ├── optimize.sql # Indexes + materialized views
│ └── deoptimize.sql # Rollback script (used by benchmark)
├── docker/
│ ├── Dockerfile.api # Production API image
│ ├── Dockerfile.seed # Cloud Run Job — loads UNSW-NB15 from GCS
│ ├── Dockerfile.tests # Cloud Run Job — performance benchmark suite
│ ├── Dockerfile.prometheus
│ └── Dockerfile.grafana
├── infra/
│ ├── docker-compose.yml # Local full-stack (API ×3, Nginx, PG, Redis, Grafana)
│ └── nginx/nginx.conf
├── ml/
│ └── train.py # Training script — RandomForest on UNSW-NB15 (40 features)
├── observability/
│ ├── prometheus.yml # Local scrape config
│ ├── prometheus_rules.yml # Alert rules: SLO + security (brute force, rate flood, ML spikes)
│ ├── gcp/prometheus.yml # GCP scrape config (Cloud Run HTTPS target)
│ └── grafana/
│ └── dashboards/
│ ├── api-dashboard.json # Performance — golden signals, latency, DB pool
│ └── security-dashboard.json # Security — auth failures, rate limits, ML detections
├── ops/
│ ├── run_tests_gcp.py # Orchestrates baseline / optimized / burst phases
│ ├── benchmark.py # Local benchmark runner
│ ├── burst_test.py # Concurrent load generator
│ └── toggle_perf.py # Enable/disable indexes + Redis via API
├── portal/ # FastAPI portal + SPA serving
├── interface/ # Threat hunting SPA (HTML/CSS/JS)
└── terraform/ # Full GCP infrastructure as code
├── main.tf # provider config, locals, labels
├── vpc.tf # VPC, subnets, VPC connector
├── cloud_sql.tf # Cloud SQL PostgreSQL 15
├── memorystore.tf # Redis Memorystore
├── cloud_run.tf # API + Portal Cloud Run services
├── load_balancer.tf # Global HTTPS load balancer + URL map
├── secrets.tf # Secret Manager resources
├── iam.tf # Service accounts + IAM roles
├── artifact_registry.tf # Docker image registry
└── storage.tf # GCS bucket (dataset + results)
```
## 本地环境搭建
**前置条件:** Docker,Docker Compose
```
git clone https://github.com/Damien-Mrgnc/threat-hunting-api.git
cd threat-hunting-api
# 1. 配置环境
cp infra/.env.example infra/.env
# 使用您的凭据编辑 infra/.env
# 2. 训练机器学习模型(仅首次)
pip install scikit-learn joblib pandas numpy
python ml/train.py # → api/ml/model.pkl
# 3. 启动完整堆栈
cd infra && docker compose up -d
# 4. 加载 UNSW-NB15 数据集
docker compose exec api python /db/seed.py
# 5. 应用 SQL 优化
docker compose exec api psql $DATABASE_URL -f /db/optimize.sql
```
| 服务 | URL | 凭据 |
|------|-----|--------|
| Portal | `http://localhost/` | — |
| API Swagger | `http://localhost/api/docs` | — |
| 威胁界面 | `http://localhost/interface/` | admin / secret |
| Grafana(性能) | `http://localhost/grafana/d/api-performance` | admin / admin |
| Grafana(安全) | `http://localhost/grafana/d/threat-security-v1` | admin / admin |
| Prometheus | `http://localhost/prometheus/` | — |
## GCP 部署
**前置条件:** `gcloud` CLI,`terraform` >= 1.7,`docker`,已启用计费的 GCP 项目
```
# 1. 身份验证
gcloud auth login && gcloud auth application-default login
# 2. 配置 Terraform
cp terraform/terraform.tfvars.example terraform/terraform.tfvars
# 编辑 terraform.tfvars:project_id、region、db_password
# 3. 构建并推送 Docker 镜像
REGISTRY="-docker.pkg.dev//threat-hunting"
docker build -t $REGISTRY/api:latest -f docker/Dockerfile.api ./api
docker push $REGISTRY/api:latest
# 4. 部署完整基础设施(约 5 分钟)
cd terraform && terraform init && terraform apply
# 5. 通过 Cloud SQL Auth Proxy 初始化数据库
./cloud-sql-proxy ::threat-hunting-db &
psql $DATABASE_URL -f db/schema.sql
# 6. 运行性能基准测试
gcloud run jobs execute threat-hunting-tests \
--region= --project= --wait
```
### CI/CD 配置(GitHub Actions)
**密钥**(`Settings → Secrets and variables → Actions`):
| 密钥 | 说明 |
|------|------|
| `GCP_SA_KEY` | 拥有 `roles/run.admin`、`roles/artifactregistry` 的 GCP 服务账户 JSON 密钥 |
**变量**(`Settings → Secrets and variables → Actions → Variables`):
| 变量 | 示例 |
|------|------|
| `GCP_PROJECT_ID` | `threat-hunting-api-2026` |
| `GCP_REGION` | `europe-west1` |
| `GAR_REGION` | `europe-west1` |
## API 端点
| 方法 | 端点 | 认证 | 描述 |
|------|------|------|------|
| `POST` | `/auth/token` | — | 获取 JWT 令牌 |
| `GET` | `/health` | — | 健康检查 + 副本信息 |
| `GET` | `/metrics` | — | Prometheus 指标(OpenMetrics) |
| `GET` | `/events/search` | JWT | 按源 IP 搜索事件(索引 + 缓存) |
| `GET` | `/events/top/attack-categories` | JWT | 攻击类别 Top 统计 |
| `GET` | `/events/stats/bytes-by-proto` | JWT | 按协议统计流量(物化视图) |
| `POST` | `/reports/generate` | JWT | 异步报告生成 |
| `GET` | `/reports/{id}` | JWT | 下载生成的报告 |
| `POST` | `/config/features` | JWT(管理员) | 运行时切换 Redis 缓存 / SQL 索引 |
| `POST` | `/detect` | JWT | **ML** — 将网络事件分类为正常/攻击 |
| `GET` | `/detect/model/info` | JWT | **ML** — 模型元数据与 ROC-AUC 评分 |
| `GET` | `/detect/intel/{ip}` | JWT | **威胁情报** — AbuseIPDB IP 信誉检查 |
完整的交互式文档可在 `/api/docs`(Swagger UI)中访问。
## 可观测性
### Grafana 仪表板
| 仪表板 | 面板 |
|--------|------|
| **API 性能** | RPS、P50/P95/P99 延迟、错误率、数据库连接池饱和度 |
| **安全** | 认证失败(401)、速率限制命中(429)、ML 攻击率、威胁情报标记、按端点的错误分类 |
### Prometheus 告警规则
| 告警 | 条件 | 严重级别 |
|------|------|----------|
| `HighErrorRate` | > 5% 的请求返回 5xx | critical |
| `SlowQueries` | P99 延迟 > 2s | warning |
| `DBPoolSaturation` | > 18/20 连接被占用 | critical |
| `APIDown` | 30 秒内未收到指标 | critical |
| `BruteForceAttempt` | 5 分钟内 > 30 次认证失败 | warning |
| `SustainedAuthFailures` | 10 分钟内 > 10 次失败 | critical |
| `RateLimitFlood` | 1 分钟内 > 60 次限流拒绝 | warning |
| `UnauthorizedAdminAccess` | 5 分钟内 > 10 次 403 拒绝 | warning |
| `HighMLAttackDetectionRate` | ML 每秒标记 > 5 次攻击事件 | warning |
| `ThreatIntelFlagsSpike` | 5 分钟内 > 20 个 IP 被 AbuseIPDB 标记 | warning |
## 已知限制与改进建议
| 限制 | 根本原因 | 改进建议 |
|------|----------|----------|
| 突发数据库测试 — 10K 并发成功率仅 1.3% | `db-g1-small` 最大连接数仅 25 | 使用 PgBouncer 或升级至 `db-n1-standard-2` |
| `/top/attack-categories` P50 ~17 秒 | `attack_cat` 列缺少索引 | 建立专用的物化视图 |
| 自签名 TLS 证书 | 未配置 DNS 域名 | 使用 GCP 托管证书(自动更新的 Let's Encrypt) |
| ML 模型未自动重训练 | 静态工件提交到 Git | 定时重训练的 Cloud Run Job 并将模型存储于 GCS |
## 文档
| 文档 | 内容 |
|------|------|
| [`docs/STACK.md`](docs/STACK.md) | 技术选型与理由 |
| [`docs/SECURITY.md`](docs/SECURITY.md) | 安全措施 — 网络、应用、密钥 |
| [`upgrade/RAPPORT_DEPLOIEMENT.md`](upgrade/RAPPORT_DEPLOIEMENT.md) | 完整的 GCP 部署报告 — 修复 14 个 Bug,基础设施细节 |
| [`upgrade/RAPPORT_PERFORMANCE.md`](upgrade/RAPPORT_PERFORMANCE.md) | 自动生成的基准报告 — 各阶段的 P50/P95/P99 |
| [`upgrade/AMELIORATIONS.md`](upgrade/AMELIORATIONS.md) | 上线后的改进路线图 |
标签:AMSI绕过, Apex, API集成, AV绕过, Backdoors, bcrypt, B-Tree 索引, Cloud Run, Cloud SQL, DoS, EC2, ECS, Exploits, FastAPI, GCP, Google Cloud Platform, Grafana, HTTPS, IaC, IaC 安全扫描, JWT, Memorystore, ML 模型, PostgreSQL, Pydantic, Python 3.12, Redis, Redis 缓存, REST API, SAST, SlowAPI, SQLAlchemy, SQL 优化, SSL/TLS, Terraform, UNSW-NB15, VPC, 全局负载均衡, 可观测性, 威胁情报, 威胁检测, 容器安全扫描, 开发者工具, 异常检测, 性能优化, 搜索引擎查询, 机器学习, 检测绕过, 测试用例, 盲注攻击, 私有网络, 网络攻击分类, 自定义请求头, 请求拦截, 负载均衡, 逆向工具