AreteDriver/overwatch

GitHub: AreteDriver/overwatch

该项目是一个战术 ISR 仪表板,旨在将 YOLO 目标检测、OSINT 情报和无人机遥测数据融合为统一的作战态势图以辅助决策。

Stars: 0 | Forks: 0

# Overwatch 战术 ISR 仪表板,将 YOLO 目标检测、OSINT 情报源和无人机遥测数据整合为统一的作战态势图。 专为 mesh-net ISR 工作流构建 —— 从摄像头、无人机和新闻管道摄取数据,然后在一个仪表板中进行可视化、关联和决策。 ## 功能 - **多源数据摄取** — 用于 YOLO 检测、OSINT 情报(TheWire-STT 格式)以及无人机/传感器遥测的 REST 端点 - **YOLO 自动监控器** — CLI 监控目录中的 ultralytics JSON 输出,并自动将其发送到 API - **实体解析** — 将检测数据与情报提及进行交叉关联(摄像头中的人物 + 报告中提及的姓名 = 同一实体) - **自动简报** — 从摄取的数据生成 SITREP。默认基于模板,或由 Ollama 驱动 (qwen2.5:14b) - **地理围栏** — 定义多边形区域,在进出时获取警报 - **Mesh 健康** — 设备心跳追踪(在线/滞后/离线状态) - **Discord 警报** — 通过 Webhook 发送高置信度检测、低电量、地理围栏违规警报 - **实时推送** — 位于 `/ws/feed` 的 WebSocket 实时广播所有发生的事件 - **检测热力图** — 地图上随时间变化的密度可视化 - **回放模式** — 拖动时间轴进行任务后审查 - **8 标签页 Streamlit 仪表板** — 地图、时间轴、情报源、简报、实体、Mesh 健康、警报、回放 ## 快速开始 ``` git clone https://github.com/AreteDriver/overwatch cd overwatch python3 -m venv .venv && source .venv/bin/activate pip install -e ".[dev,dashboard]" # 运行数据库迁移(创建/覆盖 SQLite schema) alembic upgrade head # 启动 API server uvicorn overwatch.app:app --reload --port 8080 # 启动 dashboard(单独的终端) streamlit run dashboard/app.py --server.port 8520 # 将 YOLO output 指向它(可选) python tools/yolo_watcher.py --dir /path/to/yolo/runs --lat 46.05 --lon 14.5 ``` API 文档可在 http://localhost:8080/docs (Swagger UI) 查看。 ## 架构 ``` overwatch/ ├── overwatch/ │ ├── app.py # FastAPI entry point + WebSocket │ ├── config.py # Env-driven configuration │ ├── models.py # SQLAlchemy ORM + Pydantic schemas │ ├── database.py # Engine + session factory │ ├── events.py # In-process async event bus │ ├── security.py # Auth, rate-limit, headers middleware │ ├── crypto.py # Optional Fernet field encryption │ ├── api/routes.py # 30+ REST endpoints │ ├── ingest/ # Detection, intel, telemetry adapters │ │ ├── detections.py # YOLO detection ingestion │ │ ├── intel.py # OSINT intel ingestion │ │ ├── telemetry.py # Drone/sensor telemetry │ │ └── thewire_adapter.py # TheWire-STT format adapter │ └── analysis/ │ ├── alerts.py # Threshold alerts + Discord webhook │ ├── briefing.py # Template briefing generator │ ├── ollama_briefing.py # Local Ollama LLM briefings │ ├── entities.py # Entity extraction + resolution │ ├── geofence.py # Geofence CRUD + point-in-polygon │ ├── mesh_health.py # Device heartbeat tracking │ └── replay.py # Time-windowed data retrieval ├── alembic/ # Database migrations (Alembic) ├── dashboard/app.py # Streamlit dashboard (8 tabs) ├── tools/yolo_watcher.py # CLI: watch dir for YOLO output ├── scripts/ # Dev tooling (mypy ratchet, etc.) ├── retention.py # Data retention + auto-purge └── tests/ # 290+ tests, 85% coverage ``` **技术栈**:FastAPI + SQLAlchemy + SQLite (WAL 模式) + Streamlit + Folium + Plotly ## API 端点 ### 摄取 | 方法 | 路径 | 描述 | |--------|------|-------------| | POST | `/api/detections` | 摄取 YOLO 检测数据 | | POST | `/api/detections/batch` | 批量摄取检测数据 | | POST | `/api/intel` | 摄取情报报告 | | POST | `/api/intel/batch` | 批量摄取情报 | | POST | `/api/telemetry` | 摄取遥测读数 | | POST | `/api/telemetry/batch` | 批量摄取遥测数据 | ### 查询 | 方法 | 路径 | 描述 | |--------|------|-------------| | GET | `/api/detections` | 列出检测数据(可过滤) | | GET | `/api/intel` | 列出情报报告 | | GET | `/api/telemetry` | 列出遥测读数 | | GET | `/api/entities` | 列出已解析的实体 | | GET | `/api/entities/{id}/timeline` | 实体事件时间轴 | | GET | `/api/alerts` | 列出警报 | | PATCH | `/api/alerts/{id}/acknowledge` | 确认警报 | ### 分析 | 方法 | 路径 | 描述 | |--------|------|-------------| | POST | `/api/briefing/generate` | 生成 SITREP 简报 | | GET | `/api/briefing/latest` | 获取最新简报 | | GET | `/api/mesh/health` | Mesh 节点健康状态 | | GET | `/api/replay` | 时间窗口回放数据 | | GET | `/api/dashboard/stats` | 仪表板统计摘要 | ### 地理围栏 | 方法 | 路径 | 描述 | |--------|------|-------------| | POST | `/api/geofences` | 创建地理围栏区域 | | GET | `/api/geofences` | 列出地理围栏 | | DELETE | `/api/geofences/{id}` | 删除地理围栏 | ### 导出 | 方法 | 路径 | 描述 | |--------|------|-------------| | GET | `/api/export/detections.csv` | 将检测数据导出为 CSV | | GET | `/api/export/detections.geojson` | 将检测数据导出为 GeoJSON | | GET | `/api/export/intel.csv` | 将情报报告导出为 CSV | | GET | `/api/export/telemetry.csv` | 将遥测数据导出为 CSV | | GET | `/api/export/telemetry.geojson` | 将遥测数据导出为 GeoJSON | ### 管理 | 方法 | 路径 | 描述 | |--------|------|-------------| | POST | `/api/admin/purge` | 手动清理旧记录 | ### 系统 | 方法 | 路径 | 描述 | |--------|------|-------------| | GET | `/health` | 健康检查(丰富版 — 计数、数据库大小、WS 连接数) | | WS | `/ws/feed` | 实时事件流 | ## 环境变量 | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `OVERWATCH_DATABASE_URL` | `~/.overwatch/overwatch.db` | SQLite 数据库路径 | | `OVERWATCH_API_KEY` | _(空 = 开放模式)_ | 用于身份验证的 API key | | `OVERWATCH_CORS_ORIGINS` | `*` | 允许的 CORS 来源(逗号分隔) | | `OVERWATCH_RATE_LIMIT` | `120` | 每个 IP 每个时间窗口的最大请求数 | | `OVERWATCH_RATE_WINDOW` | `60` | 速率限制时间窗口(秒) | | `OVERWATCH_DISCORD_WEBHOOK` | _(空)_ | 用于警报的 Discord Webhook URL | | `OVERWATCH_ALERT_CONFIDENCE` | `0.9` | 高置信度检测阈值 | | `OVERWATCH_ALERT_BATTERY` | `20.0` | 低电量警报阈值 (%) | | `OVERWATCH_DEVICE_STALE_SECONDS` | `300` | 设备被标记为滞后前的秒数 | | `OVERWATCH_DEVICE_OFFLINE_SECONDS` | `900` | 设备被标记为离线前的秒数 | | `OVERWATCH_ENCRYPTION_KEY` | _(空)_ | 用于字段加密的 Fernet key | | `OLLAMA_URL` | `http://localhost:11434` | Ollama API 端点 | | `OLLAMA_MODEL` | `qwen2.5:14b` | 用于 LLM 简报的模型 | | `OLLAMA_ENABLED` | `false` | 启用 Ollama 驱动的简报 | | `OVERWATCH_RETENTION_DAYS` | `30` | 自动清理超过 N 天的记录(0 = 永久保留) | | `OVERWATCH_PURGE_INTERVAL_HOURS` | `6` | 运行自动清理的频率(小时) | ## 安全 - **API key 认证**:设置 `OVERWATCH_API_KEY` 以启用。支持 `Authorization: Bearer ` 标头、`X-API-Key` 标头或 WebSocket `?key=` 查询参数。留空 = 开放模式(开发环境) - **安全标头**:HSTS、X-Content-Type-Options、X-Frame-Options、XSS-Protection、Referrer-Policy、Permissions-Policy - **速率限制**:基于 IP 的滑动窗口 - **CORS**:可配置的允许来源 - **字段加密**:针对敏感字段的可选 Fernet (AES-128-CBC)。需要 `cryptography` 包 ## 部署 作为两个应用部署在 [Fly.io](https://fly.io) 上: | 应用 | URL | 配置 | |-----|-----|--------| | API | https://overwatch-isr.fly.dev | `fly.toml` | | 仪表板 | https://overwatch-dashboard.fly.dev | `fly.dashboard.toml` | ``` # 部署 API flyctl deploy -a overwatch-isr --wait-timeout 600 # 部署 Dashboard flyctl deploy --config fly.dashboard.toml --wait-timeout 600 ``` ## 开发 ``` # 运行测试 pytest # All tests pytest -m smoke # Smoke/integration tests pytest --cov=overwatch # With coverage report # Lint(始终同时运行两者) ruff check . ruff format . # Type check python -m mypy overwatch --ignore-missing-imports --show-error-codes --no-error-summary # Type ratchet(如果任何 module 超过其 error ceiling 则失败) python scripts/mypy-ratchet.py ``` ## 集成点 - **[Dossier](https://github.com/AreteDriver/Dossier)** — 使用基于 ML 的 NER + 实体解析器直接替代正则表达式实体提取 - **[Animus](https://github.com/AreteDriver/animus)** — 用 AI 编排的上下文感知生成替代模板/Ollama 简报 - **TheWire-STT** — 从现有的 OSINT API 格式拉取 (GET `/api/stories`) - **YOLO** — 通过监控器 CLI 或直接 POST 接收 ultralytics JSON 输出 - **Discord** — 针对高置信度检测、低电量、地理围栏违规的 Webhook 警报 ## 许可证 私有仓库。
标签:AI风险缓解, DFIR, Kubernetes, 逆向工具