robyroro/openlens
GitHub: robyroro/openlens
OpenLens 是一个开源的被动 OSINT 调查工作台,将公开标识符转化为带完整证据溯源和完整性校验的实体关系图,服务于防御性安全和尽职调查等合法研究场景。
Stars: 0 | Forks: 0
# OpenLens
OpenLens 是一个开源的、证据优先的 OSINT 调查工作台。它将公开标识符转化为可追踪的实体图,同时为每条证据保留来源、收集时间、置信度、原始观测数据以及 SHA-256 完整性指纹。




*运维控制台将可解释的检测、发现分类、计划监控任务、保存的图查询、STIX 交换以及报告生成整合到一个案例工作区中。*
## 当前可用功能
- 包含域名、IP、邮箱、URL 和用户名 Seed 的案例管理
- 在收集边界进行严格的标准化和验证
- 被动的 DNS-over-Https、RDAP 和证书透明度收集器
- 用于演示、测试和产品评估的离线确定性收集器
- 实体去重、类型化关系、置信度评分以及来源失败隔离
- 交互式关系图、证据浏览器、调查时间线和来源逐层追踪
- 使用 PageRank、度中心性和中介中心性、连通分量、关节点、拓扑密度和最短路径追踪的图分析
- 每个 Seed 的收集器遥测数据,包含延迟、成功率、记录数和来源错误历史
- 分析师笔记本,包含结构化假设、已确认/已驳回断言、依据和证据链接
- 具有图哈希值和自动变更差异对比的不可变调查快照
- SHA-256 Merkle 完整性清单和基于标准的 STIX 2.1 交换包
- 案例范围的检测规则,具有去重的发现、严重性、发生次数追踪和分类功能
- 选择启用的计划监控任务以及用于有界连续收集的显式手动运行
- 图形查询实验室,支持类型、置信度、文本、关系和跳数受限的遍历筛选器
- 保存的图查询、STIX 2.1 摄取以及链接到证据的 Markdown 分析师报告
- JSON 案例包、CSV 证据表和双向威胁情报交换
- 案例范围的审计事件和内容完整性哈希
- SQLite 提供零配置使用;SQLAlchemy 使数据层随时可支持 PostgreSQL
- Docker Compose 部署和详细的插件接口文档
## 安全与预期用途
OpenLens 专为使用公开数据进行合法研究而设计:防御性安全、尽职调查、新闻报道、品牌保护和威胁情报。内置的收集器都是被动的,仅查询有公开文档的服务。本应用程序有意**不**包含凭证攻击、隐身、CAPTCHA 绕过、私人数据代理、侵入式端口扫描或任意 URL 抓取。
您需对授权、当地法律、来源条款和数据保留义务负责。请勿使用 OpenLens 骚扰他人、规避访问控制或收集您无权处理的数据。有关操作指南,请参阅 [SECURITY.md](SECURITY.md)。
## 使用 Docker 快速开始
环境要求:带有 Compose 的 Docker Desktop。
```
docker compose up --build
```
访问地址:
- 工作台:
- API 文档:
- 健康检查:
数据存储在指定的 `openlens-data` 卷中。
## 本地开发
环境要求:Python 3.11+ 和 Node.js 22.12+。
后端:
```
cd backend
python -m venv .venv
.\.venv\Scripts\python -m pip install -e ".[dev]"
.\.venv\Scripts\uvicorn app.main:app --reload
```
前端,在第二个终端中运行:
```
cd frontend
npm install
npm run dev
```
Vite 开发服务器将 `/api` 代理到 `http://127.0.0.1:8000`。
## 架构
```
flowchart TD
UI["React investigation workbench"] --> API["FastAPI case API"]
API --> ORCH["Bounded collection orchestrator"]
ORCH --> SOURCES["Passive DNS / RDAP / CT / offline demo"]
ORCH --> PIPE["Normalization + evidence pipeline"]
PIPE --> DB["SQLAlchemy case graph"]
DB --> ANALYTICS["Topology + path + snapshot analytics"]
DB --> RULES["Detection rule engine"]
SCHED["Opt-in monitor scheduler"] --> ORCH
STIX["STIX 2.1 ingest"] --> PIPE
ANALYTICS --> REPORT["Reports + JSON / CSV / STIX exports"]
RULES --> UI
REPORT --> UI
```
核心记录包括 `Case`、`Seed`、`Investigation`、`Entity`、`Relation`、`Evidence`、`DetectionRule`、`Finding`、`Monitor`、`SavedGraphQuery` 和 `AuditEvent`。关系引用支持它们的证据记录。重复的观测会更新实体的最后发现时间和置信度,而不是创建重复的图节点。发现使用稳定的指纹,因此重复出现的信号会增加其发生次数计数,而不会淹没分析队列。
## API 概述
| 方法 | 路由 | 用途 |
|---|---|---|
| `GET` | `/api/collectors` | 发现已安装的数据源和受支持的输入 |
| `POST` | `/api/cases` | 创建带有可选 Seed 的案例 |
| `POST` | `/api/cases/{id}/seeds` | 添加类型化且经过验证的 Seed |
| `POST` | `/api/cases/{id}/investigations` | 运行选定的收集器 |
| `GET` | `/api/cases/{id}/graph` | 读取标准化的实体和关系 |
| `GET` | `/api/cases/{id}/evidence` | 搜索和筛选证据 |
| `GET` | `/api/cases/{id}/timeline` | 读取审计和证据事件 |
| `GET` | `/api/cases/{id}/analytics` | 计算图拓扑和中心性指标 |
| `GET` | `/api/cases/{id}/path` | 查找两个实体之间的最短关系链 |
| `GET` | `/api/cases/{id}/source-health` | 检查收集器的可靠性和延迟 |
| `POST` | `/api/cases/{id}/notes` | 记录分析师的观察结果或警告 |
| `POST` | `/api/cases/{id}/assertions` | 添加结构化且关联证据的分析师主张 |
| `GET` | `/api/cases/{id}/snapshots/diff` | 比较最新的图快照 |
| `GET` | `/api/cases/{id}/integrity` | 生成证据 Merkle 清单 |
| `POST` | `/api/cases/{id}/rules/evaluate` | 评估已启用的检测规则 |
| `GET` | `/api/cases/{id}/findings` | 读取去重后的发现队列 |
| `POST` | `/api/cases/{id}/monitors` | 创建选择启用的定期收集计划 |
| `POST` | `/api/cases/{id}/query` | 执行受限的图查询 |
| `POST` | `/api/cases/{id}/saved-queries` | 持久化可复用的图视图 |
| `POST` | `/api/cases/{id}/import/stix` | 摄取并合并 STIX 2.1 包 |
| `GET` | `/api/cases/{id}/report.md` | 生成 Markdown 分析师报告 |
| `GET` | `/api/cases/{id}/export.json` | 导出带有版本的案例包 |
| `GET` | `/api/cases/{id}/evidence.csv` | 导出扁平化的证据表 |
| `GET` | `/api/cases/{id}/export.stix.json` | 导出 STIX 2.1 包 |
FastAPI 在 `/docs` 和 `/openapi.json` 公开完整的 OpenAPI 契约。
## 持续监控
在调度器关闭时创建监控定义是安全的。手动运行监控依然可以在运维视图中使用。要启用自动的到期监控执行,请显式设置:
```
OPENLENS_SCHEDULER_ENABLED=true
OPENLENS_SCHEDULER_POLL_SECONDS=30
```
调度器会创建常规的调查,因此来源隔离、速率间隔、来源溯源、快照、规则评估和审计事件的应用方式与手动收集完全相同。
## 添加收集器
收集器位于 `backend/app/collectors` 中。每个适配器都会声明其支持的实体类型,并返回标准化的发现结果,而不直接写入数据库:
```
class MyCollector(Collector):
name = "my_source"
description = "What public source this queries"
supported_kinds = frozenset({EntityKind.DOMAIN})
passive = True
async def collect(self, kind, normalized_value, client):
return CollectorResult(
entities=[DiscoveredEntity(EntityKind.DOMAIN, normalized_value)],
evidence=[CollectedEvidence(
title="Public observation",
summary="What the source established",
raw_data={"field": "value"},
source_url="https://source.example/record",
)],
)
```
在 `collectors/registry.py` 中注册一个实例。适配器应使用注入的 HTTP 客户端,不得接受任意目标 URL,应仅保留相关的响应字段,并且必须记录 API 密钥或使用条款要求。
## 测试与质量检查
```
cd backend
.\.venv\Scripts\ruff check app tests
.\.venv\Scripts\pytest --cov=app
cd ..\frontend
npm test
npm run build
```
## 路线图
- Alembic 迁移和一流的 PostgreSQL 部署
- 调查员账户、案例级别的 RBAC 和加密的秘密存储
- 针对每台主机和每个提供商的令牌桶速率策略
- 证据审查状态、分配和多分析师发现工作流
- 针对 MISP、TAXII 和常见图格式的额外兼容适配器
- 用于捕获的可选对象存储和已签名的证据清单
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
标签:DFIR, MITM代理, 请求拦截, 逆向工具