BenJonesVA/vt-to-misp
GitHub: BenJonesVA/vt-to-misp
一个透明的 VirusTotal API 代理,使用 Redis 缓存查询结果并将威胁情报自动写入 MISP,兼容现有 VT 客户端实现即插即用。
Stars: 0 | Forks: 0
# vt-to-misp
[](LICENSE)
[](package.json)
[](tsconfig.json)
[](package.json)
一个 VirusTotal API 代理,它可以透明地将结果缓存到 Redis 中,并将威胁情报写入 MISP。现有的 VirusTotal 客户端只需更改其 base URL —— 所有的 API 路径和 `x-apikey` header 都会保持不变。
## 工作原理
每次查询都遵循一个 3 层链:
```
Request
│
▼
Redis cache ──hit──► Return (X-Cache: HIT)
│
miss
│
▼
MISP search ──found──► Repopulate Redis ──► Return (X-Cache: MISP)
│
not found
│
▼
VirusTotal API ──► Store in Redis ──► Write MISP event ──► Return (X-Cache: MISS)
```
**核心特性:**
- MISP 故障永远不会阻断查询 —— 代理会直接回退到 VirusTotal
- Redis 不可用会降低性能,但绝不会中断服务
- 子资源(`/comments`、`/behaviours` 等)会被缓存在 Redis 中,但不会触发 MISP 写入
## 快速开始
```
cp .env.example .env
# 填写 VT_API_KEY、PROXY_API_KEY、MISP_API_KEY 以及任何密码
docker compose up -d
```
代理监听 `http://localhost:${PROXY_PORT}`(默认为 `3000`)。将你的 VT 客户端指向该地址即可。
## 配置
所有配置均通过环境变量完成。复制 `.env.example` 为 `.env` 即可开始配置。
### 代理设置
| 变量 | 描述 | 默认值 |
|---|---|---|
| `VT_API_KEY` | 你的 VirusTotal API key | — |
| `PROXY_API_KEY` | 客户端必须通过 `x-apikey` 发送的 API key | — |
| `REDIS_URL` | Redis 连接 URL | `redis://:redispassword@redis:6379` |
| `CACHE_TTL_SECONDS` | 缓存的 VT 响应的 TTL | `86400` |
| `CACHE_NOT_FOUND_TTL_SECONDS` | 缓存的 404 响应的 TTL | `3600` |
| `MISP_URL` | MISP 实例的 base URL | `https://misp-core` |
| `MISP_API_KEY` | MISP 自动化 key | — |
| `MISP_VERIFY_SSL` | 验证 MISP TLS 证书 | `false` |
| `MISP_ORG_ID` | 新 MISP 事件的组织 ID | `1` |
| `MISP_DISTRIBUTION` | 新 MISP 事件的分发级别 | `0` |
| `PORT` | 代理监听的内部端口 | `3000` |
| `PROXY_PORT` | 映射到代理容器的主机端口 | `3000` |
### MISP / 数据库设置
有关 MISP 构建时变量、数据库凭据、Redis 密码以及可选的邮件/同步服务器设置的完整列表,请参阅 `.env.example`。
## API 兼容性
对于四种主要资源类型,代理暴露了与 VirusTotal v3 API 相同的路径:
| 资源 | 路径 |
|---|---|
| 文件 | `GET /api/v3/files/{hash}` |
| URL | `GET /api/v3/urls/{id}` |
| IP 地址 | `GET /api/v3/ip_addresses/{ip}` |
| 域名 | `GET /api/v3/domains/{domain}` |
所有四种类型均支持子资源(例如 `/comments`、`/behaviours`、`/relationships/{rel}`)。
### 响应 header
| Header | 值 | 含义 |
|---|---|---|
| `X-Cache` | `HIT` / `MISP` / `MISS` | 哪一层提供了响应 |
| `X-MISP-Event-ID` | 事件 ID | 当存在 MISP 事件时显示(在 `HIT` 时不存在) |
### 可选请求 header
| Header | 描述 |
|---|---|
| `x-misp-event-id` | 将 VT 结果附加到现有的 MISP 事件中,而不是创建新事件 |
### 管理 endpoint
| 方法 | 路径 | 描述 |
|---|---|---|
| `GET` | `/health` | 存活状态检查 |
| `GET` | `/cache/stats` | Redis 缓存统计信息 |
| `DELETE` | `/cache/:type/:id` | 从缓存中驱逐特定条目 |
## MISP 事件结构
每个事件包含:
- 原生 MISP 属性:`md5`、`sha256`、`url`、`ip-dst`、`domain`,以及带有 VT 摘要的 `comment`
- 一个原始 `text` 属性(`comment: "vt-raw-response"`)用于存储完整的 VT JSON —— 这使得代理可以直接从 MISP 重新填充 Redis,而无需再次调用 VirusTotal
## Docker Compose 服务
| 服务 | 镜像 |
|---|---|
| `proxy` | 基于此仓库构建 |
| `redis` | `valkey/valkey:7.2` |
| `misp-core` | `ghcr.io/misp/misp-docker/misp-core` |
| `misp-modules` | `ghcr.io/misp/misp-docker/misp-modules` |
| `db` | `mariadb:10.11` |
| `mail` | `ghcr.io/egos-tech/smtp` |
| `misp-guard` | `ghcr.io/misp/misp-docker/misp-guard`(可选,通过 `COMPOSE_PROFILES=misp-guard` 启用) |
## 开发
**前置条件:** Node.js 20+,npm
```
npm install
npm run dev # hot-reload via tsx watch
npm run build # compile TypeScript → dist/
npm start # run compiled output
npm test # run test suite once
npm run test:watch # run tests in watch mode
```
运行单个测试文件:
```
npx vitest run tests/path/to/file.test.ts
```
### 技术栈
- **Runtime:** Node.js 搭配 [Fastify](https://fastify.dev/)
- **语言:** TypeScript(ESM,NodeNext 模块解析)
- **缓存:** ioredis
- **HTTP 客户端:** Axios
- **配置验证:** Zod
- **测试:** Vitest + ioredis-mock + nock
标签:API代理, GNU通用公共许可证, MITM代理, Node.js, Redis, TypeScript, 威胁情报, 安全插件, 开发者工具, 搜索引擎查询, 版权保护, 自动化攻击, 请求拦截