damianr93/cogni-threat-back
GitHub: damianr93/cogni-threat-back
基于 NestJS 和 Prisma 构建的开源威胁情报平台后端,提供多源漏洞同步、勒索软件监控、资产匹配告警及 AI 辅助分析能力。
Stars: 0 | Forks: 0
# Cogni-Threat - 后端
使用 NestJS、TypeScript 和 Prisma 开发的后端,用于网络威胁的管理、监控和分析。
## 使用 Docker 快速开始
这是推荐给社区用户的路径。请将 `cogni-threat` 和 `cogni-threat-front` 保留为同级目录,然后从这个后端仓库运行整个技术栈。
```
corepack enable
cp .env.template .env
docker compose up --build
```
默认的 compose 技术栈会启动 PostgreSQL、NestJS API 和前端容器。前端默认在 `http://localhost:8080` 暴露,并将 API 流量代理到后端容器。
当您需要更改主机端口时,请使用 `API_HOST_PORT`、`FRONT_PORT` 和 `DB_PORT`。除非您有意更改 API 容器内部使用的端口,否则请保持 `API_PORT=3000`。
在首次启动之前,请在 `.env` 中设置 `ADMIN_EMAIL` 和 `ADMIN_PASSWORD`。API 会在启动期间自动创建或更新该用户为 `ADMIN/WRITE`,以便首次登录后可以从 UI 继续进行设置。
在将生产环境部署公开之前,请为 `DB_PASSWORD`、`JWT_SECRET`、`SECRETS_MASTER_KEY`、`ADMIN_PASSWORD` 和 `CORS_ORIGIN` 设置强值。
登录后,转到 **管理 → 来源、凭证和 AI** 以配置外部 API 凭证和 Ollama/RAG 设置。从面板存储的 Ollama 值会覆盖 `.env` 中的回退值,无需重启容器。
## AI 提供商与 Embeddings
CogniThreat 使用 **Ollama** 作为内置的开源 AI 提供商,用于聊天和 embeddings。这使得默认设置保持自托管状态,并且不需要付费的 API key。
可以从管理面板进行配置:
* Ollama URL。
* 聊天模型。
* Embedding 模型。
* RAG 检索和生成参数。
`EMBEDDING_DIM` 保留在 `.env` 中,因为它必须与存储在 PostgreSQL/pgvector 中的向量维度相匹配。如果您切换到具有不同维度的 embedding 模型,请在索引数据之前更新 `EMBEDDING_DIM` 并重建/重新索引 embeddings。在数据存在后更改它需要重新生成向量索引。
目前尚不支持兼容 OpenAI 的 API。添加它们应作为一个显式的提供商选项(`ollama` / `openai`),并带有单独的 API-key、聊天模型、embedding 模型和 base-URL 设置。
## Docker 冒烟测试
在发布版本或分享设置说明之前使用此命令:
```
docker compose up --build
curl http://localhost:3000/health
```
然后打开 `http://localhost:8080` 并使用通过 `ADMIN_EMAIL` 和 `ADMIN_PASSWORD` 配置的管理员账号登录。
## 使用的技术
* NestJS
* TypeScript
* Prisma ORM
* PostgreSQL
* Swagger
* Docker
* pnpm
# 环境要求
* 推荐的完整技术栈设置需要 Docker 和 Docker Compose。
* 本地后端开发需要 Node.js 22 或更高版本以及 pnpm。
* 如果在没有 Docker 的情况下运行后端,则需要 PostgreSQL。
该项目使用 Corepack 来管理 pnpm 的版本。
# 本地开发
克隆仓库:
```
git clone
cd cogni-threat-back
```
安装依赖:
```
corepack enable
pnpm install
```
# 配置
复制示例文件:
```
cp .env.template .env
```
配置所需的变量:
```
DATABASE_URL=
PORT=3000
```
# 数据库
该应用程序通过 Prisma 使用 PostgreSQL。
## 生成 Prisma 客户端
```
pnpm run db:generate
```
## 应用 schema
```
pnpm run db:push
```
# 身份验证
API 使用 JWT 登录,并将 IP 白名单作为第一道访问防线。
角色和权限:
* `ADMIN`:在整个应用程序中具有读写权限。
* `USER` 且具有 `READ`:只读访问权限。
* `USER` 且具有 `WRITE`:读取和启用的写入操作权限。
创建或更新第一个管理员:
```
ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD='cambiar-esta-clave' pnpm run seed:admin
```
在 Docker 中,当 `.env` 中存在 `ADMIN_EMAIL` 和 `ADMIN_PASSWORD` 时,API 会在启动时自动运行此引导程序。
主要 endpoints:
* `POST /auth/login`
* `POST /auth/register`
* `GET /auth/me`
* `GET /admin/users` (`ADMIN`)
* `PUT /admin/users/:id` (`ADMIN`)
* `DELETE /admin/users/:id` (`ADMIN`)
前端包含一个仅对 `ADMIN` 用户可见的 `/admin` 面板,从中可以查看用户、更改角色/权限、激活/停用账户以及删除用户。
修改 `prisma/schema.prisma` 后,运行:
```
pnpm run db:generate
```
# 运行
## 开发环境
```
pnpm run start:dev
```
## 使用 Docker 的生产环境
```
docker compose -f docker-compose.prod.yml up --build -d
```
## 不使用 Docker 的生产环境
```
pnpm run build
pnpm run start:prod
```
# 测试
## 单元测试
```
pnpm test
```
## 集成测试 (E2E)
```
pnpm run test:e2e
pnpm run test:e2e -- test/vuln-sync.e2e-spec.ts
```
## 弹性同步(关键 specs)
```
pnpm test -- date-range.util.spec
pnpm test -- nvd.collector.spec
pnpm test -- osv.collector.spec
pnpm test -- sync-recovery.service.spec
```
# 弹性同步
## Vuln Monitor
每个源将 watermark 保存在 `vuln_sync_state.lastSyncAt` 中(数据同步到的最后日期)。
| 来源 | 故障后恢复 |
|--------|-------------------------|
| NVD | 90 天的时间窗口(`lastModStartDate`/`lastModEndDate`),按 chunk 设置 checkpoint |
| GitHub / OSV | 按日期增量同步;OSV 每 200 个 ID 设置 checkpoint |
| KEV / EPSS | 定期全量刷新 |
### Endpoints
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| GET | `/sync/status` | 各来源的状态 |
| POST | `/sync/trigger` | 手动增量同步(需要 write 权限) |
| POST | `/sync/backfill` | 按日期回填:`{ source, since, until? }` |
回填来源:`nvd`、`github`、`osv`、`kev`。显式范围 `until` 限制为 365 天。
## Ransomware
每 30 分钟运行一次的 cron 任务使用 `/victims/recent`(非详尽查询)。在长时间故障后:
- 启动时,如果 `lastSync` > `RANSOMWARE_RECOVERY_STALE_HOURS`(默认 24 小时),则按国家和群组运行完整同步。
- 手动:`POST /data-sources/recover`(需要 write 权限)。
- 群组详情同步:`POST /data-sources/sync-groups`(需要 write 权限) — 通过 `syncGroupsData` 在后台运行;进度在 `GET /data-sources/sync-groups/status`(`processed/total`)中查看;群组 UI 会查询 `GET /dashboard/sources`(`ransomware-live.lastSync`)以获取最后一次同步信息。
`.env` 中的变量:
```
RANSOMWARE_RECOVERY_STALE_HOURS=24
RANSOMWARE_RECOVERY_ON_BOOT=true
```
### 部署前检查清单
- [ ] `pnpm test` 和 `pnpm run test:e2e -- test/vuln-sync.e2e-spec.ts` 通过(变绿)
- [ ] `pnpm run build` 后端 + 前端
- [ ] `POST /sync/trigger` 响应 `{ started: true, ... }` 且数据结构(shape)无变化
- [ ] 模拟 NVD 故障:数据库中 `lastSyncAt` 过旧 → 下次同步将查询大范围时间窗口
- [ ] 模拟 ransomware 故障:`lastSync` > 24 小时 → 启动时输出恢复日志
# 漏洞告警(配置文件)
流程:**资产清单配置文件** → **订阅 vuln-monitor** → **预览** → 每 5 分钟运行一次的 cron 任务会将 CVE 与配置文件中的软件包/CPE 进行匹配。
## 配置文件(`VulnWatchProfile`)
用户(App / IT / OT)可重复使用的资产清单。每个条目定义一个匹配词(`query`),以及可选的 `vendor`、`product`、`ecosystem`。
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| GET | `/alerts/vuln-profiles` | 列出用户的配置文件(+ 条目) |
| POST | `/alerts/vuln-profiles` | 创建配置文件 |
| PUT | `/alerts/vuln-profiles/:id` | 编辑 |
| DELETE | `/alerts/vuln-profiles/:id` | 删除(级联删除条目) |
| POST | `/alerts/vuln/preview` | 预览:`{ profileIds, severities?, days?: 7, ... }` |
## 订阅 `vuln-monitor`
设置位于 `AlertSubscription.settings`:
- `profileIds`(必填,≥1)— 配置文件之间的 OR 逻辑
- `severities` — 默认 `CRITICAL`、`HIGH`
- 可选:`cvssMin`、`epssMin`、`isKevOnly`、`keywords`(与配置文件匹配项的 AND 逻辑)
处理器(`handleVulnMonitorAlerts`)对 `affectedPackages`、NVD 的 CPE 和 KEV 标题使用 `matchCveToProfiles`。Telegram 通知包含配置文件、条目、受影响的软件包以及指向 `/vuln-monitor` 的链接。
### OT 配置文件示例
```
{
"name": "Planta OT Línea 1",
"environment": "OT",
"items": [
{ "label": "Siemens S7", "query": "s7", "vendor": "siemens", "product": "s7" }
]
}
```
### 部署前效用检查清单
- [ ] 创建名为“Web 技术栈”的配置文件,包含 `nginx`、`postgresql`
- [ ] 预览显示匹配到的近期 CVE
- [ ] 创建订阅 → `POST /alerts/trigger-manual-check` → Telegram 收到包含配置文件和产品的通知
- [ ] 没有匹配到配置文件的通用 Critical CVE → 不会收到通知
- [ ] `pnpm test -- alerts/vuln` 通过(变绿)
# Docker
## 标准环境
```
docker compose up -d --build
```
## 生产环境
```
docker compose -f docker-compose.prod.yml up -d --build
```
# 项目结构
```
src/
├── modules/
│ ├── actors/
│ ├── alerts/
│ ├── countries/
│ ├── cyber-news/
│ ├── dashboard/
│ ├── data-sources/
│ ├── fake-news/
│ ├── health/
│ ├── ransomware/
│ └── vuln-monitor/
│
├── shared/
│
├── app.controller.ts
├── app.module.ts
├── app.service.ts
└── main.ts
prisma/
libs/
scripts/
test/
storage/
```
# 核心模块
* Actors
* Alerts
* Countries
* Cyber News
* Dashboard
* Data Sources
* Fake News
* Health
* Ransomware
* Vulnerability Monitor
# 重要文件
## src/main.ts
应用程序的入口点。
## src/app.module.ts
系统主模块。
## prisma/*
数据库 schema 配置与访问。
## src/modules/*
各个业务模块的实现。
## src/shared/*
共享的组件和实用工具。
## scripts/*
用于维护和数据导入的辅助脚本。
# 项目约定
## 依赖管理
始终使用:
```
pnpm
```
不要使用:
```
npm
```
或
```
yarn
```
以避免 lockfile 出现不一致。
## 环境变量
所有敏感配置必须通过环境变量声明。
不要提交到版本控制:
```
.env
```
## 代码风格
* 严格的 TypeScript。
* NestJS 模块化架构。
* Prisma 作为数据访问层。
* 使用服务处理业务逻辑。
* 控制器仅用于暴露 endpoints。
# Git 工作流
## 主开发分支
所有更改都应在以下分支上进行:
```
develop
```
常规流程:
```
git checkout develop
git pull origin develop
git add .
git commit -m "Descripción del cambio"
git push origin develop
```
## 部署
`develop` 分支用作主要的开发分支。
更改经过验证后,通过为项目配置的 CI/CD 流水线部署到相应的环境中。
请勿直接在生产服务器上进行更改。
## 最佳实践
* 开始工作前保持 `develop` 分支为最新。
* 尽可能提交描述性强且粒度较小的 commit。
* 在执行 push 之前,确认应用程序能够正确编译。
* 避免在 commit 中包含临时文件、凭证或 `.env` 文件。
标签:AI风险缓解, LLM评估, NestJS, Ollama, PostgreSQL, Prisma, RAG, TypeScript, 威胁情报, 安全插件, 开发者工具, 测试用例, 自动化攻击, 请求拦截