BenJonesVA/vt-to-misp

GitHub: BenJonesVA/vt-to-misp

一个透明的 VirusTotal API 代理,使用 Redis 缓存查询结果并将威胁情报自动写入 MISP,兼容现有 VT 客户端实现即插即用。

Stars: 0 | Forks: 0

# vt-to-misp [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Node.js](https://img.shields.io/badge/Node.js-20%2B-339933?logo=node.js&logoColor=white)](package.json) [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-3178C6?logo=typescript&logoColor=white)](tsconfig.json) [![Tests: Vitest](https://img.shields.io/badge/tests-vitest-6E9F18?logo=vitest&logoColor=white)](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, 威胁情报, 安全插件, 开发者工具, 搜索引擎查询, 版权保护, 自动化攻击, 请求拦截