JuniYadi/TrivyUI
GitHub: JuniYadi/TrivyUI
为 Trivy 扫描器提供持久化的 Web 漏洞仪表板,支持报告上传、可视化管理、邮件告警与扫描保留策略。
Stars: 0 | Forks: 0
# TrivyUI
Trivy 扫描器的漏洞仪表板
## 环境变量
将 `.env.example` 复制到 `.env`(或在运行时环境中导出这些变量)。
```
PORT=3000
API_KEY_ENABLED=false
TRIVYUI_DB_PATH=trivy.db
# MYSQL_URL=mysql://user:password@127.0.0.1:3306/trivyui
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=trivyui@company.com
SMTP_PASS=app-password-here
SMTP_FROM="TrivyUI "
SMTP_TO=devops@company.com,security@company.com
NOTIFY_ENABLED=false
NOTIFY_MIN_SEVERITY=HIGH
APP_BASE_URL=http://localhost:3000
# 可选的扫描保留(选择启用;默认保留无限期扫描)
RETENTION_ENABLED=false
RETENTION_DEFAULT_KEEP=unlimited
RETENTION_GROUP_RULES=dev-*:10,stg-*:10,prd-*:unlimited,prod-*:unlimited,production-*:unlimited
RETENTION_REPO_RULES=
```
变量参考:
- `PORT`:Bun 的 HTTP 服务器端口(默认为 `3000`)。
- `API_KEY_ENABLED`:设置为 `true` 时,启用对 `POST /api/*` 的 API 密钥强制验证。
- `TRIVYUI_DB_PATH`:当前运行时和 `bun run db:seed-dashboard` 使用的 SQLite 文件路径。
- `MYSQL_URL`:基于数据库驱动集成的 MySQL 连接字符串示例。
- `SMTP_HOST`:SMTP 服务器主机。
- `SMTP_PORT`:SMTP 服务器端口(STARTTLS 为 `587`,SMTPS 为 `465`)。
- `SMTP_SECURE`:隐式 TLS(通常为端口 `465`)时为 `true`,否则为 `false`。
- `SMTP_USER` / `SMTP_PASS`:SMTP 认证凭据。
- `SMTP_FROM`:电子邮件中显示的发件人地址。
- `SMTP_TO`:逗号分隔的收件人列表。
- `NOTIFY_ENABLED`:全局启用/禁用通知。
- `NOTIFY_MIN_SEVERITY`:最低严重性触发条件(`CRITICAL`、`HIGH`、`MEDIUM`、`LOW`、`UNKNOWN`)。
- `APP_BASE_URL`:邮件正文中用于仪表板链接的基础 URL。
- `RETENTION_ENABLED`:设置为 `true` 时启用扫描保留清理(默认为 `false`;需手动开启)。
- `RETENTION_DEFAULT_KEEP`:无规则匹配时的回退保留策略(默认为 `unlimited`)。
- `RETENTION_GROUP_RULES`:按扫描组名称以逗号分隔的 `:` 规则。
- `RETENTION_REPO_RULES`:按仓库名/镜像名以逗号分隔的 `:` 规则;优先级高于 `RETENTION_GROUP_RULES`。
实际保留示例:
- 使用 `RETENTION_GROUP_RULES=dev-*:10,stg-*:10,prd-*:unlimited,prod-*:unlimited,production-*:unlimited` 仅保留 dev/stg 组最新的 10 次扫描,同时保持 prod 组无限制。
- 设置 `RETENTION_ENABLED=true` 以应用规则;保留 `RETENTION_DEFAULT_KEEP=unlimited` 使未匹配的组/仓库不受影响。
- 将 `RETENTION_REPO_RULES=` 留空以禁用针对仓库的覆盖规则。
注意:
- `src/index.ts` 中的当前 HTTP 运行时会初始化 SQLite (`initDb()`),因此 `MYSQL_URL` 仅作为连接格式的参考被记录在文档中。
- 即使 SMTP 发送失败,上传/webhook API 仍会返回成功。
- 失败的通知尝试会以 `failed` 状态记录在 `notifications` 表中,并附带错误消息。
## 生成 Trivy JSON
首先从 Trivy 生成 JSON 报告,然后通过 UI 或 API 上传。
```
# image scan 示例
trivy image --format json --output trivy-image.json nginx:latest
# filesystem scan 示例
trivy fs --format json --output trivy-fs.json .
```
注意:
- 使用 `--format json` 和 `--output .json`。
- 将每个文件大小控制在 10 MB 以下(较大的文件会被 API 拒绝)。
## 通过 UI 上传
1. 启动应用并打开 `http://localhost:3000/upload`。
2. 选择一种输入方式:
- 文件模式:点击 `Choose Files` 或拖放一个或多个 `.json` 文件。
- 粘贴模式:从 CI 输出/产物中复制 JSON 并将其粘贴到 `Paste JSON directly` 中。
3. 点击 `Upload File` / `Upload Batch`(文件模式)或 `Upload Pasted JSON`(粘贴模式)。
行为:
- 1 个文件 -> UI 调用 `POST /api/upload`
- 多个文件 -> UI 调用 `POST /api/upload/batch`
- 粘贴的 JSON -> UI 首先验证 JSON 语法,然后调用 `POST /api/upload`
如果上传失败并提示 `INVALID_TRIVY_FORMAT`,则说明 JSON 语法有效,但不是有效的 Trivy 结果结构。
## 通过 API 上传
单文件(`file` 字段):
```
curl -X POST "http://localhost:3000/api/upload" \
-F "file=@trivy-image.json;type=application/json"
```
批量上传(`files` 字段重复):
```
curl -X POST "http://localhost:3000/api/upload/batch" \
-F "files=@trivy-image.json;type=application/json" \
-F "files=@trivy-fs.json;type=application/json"
```
预期响应:
- `201` 成功
- `400` 无效/缺失 multipart 字段
- `413` 文件过大
- `415` 不支持的内容类型
- `422` JSON 未被识别为 Trivy 结果
## 实用命令
```
PATH="$HOME/.bun/bin:$PATH" bun test
PATH="$HOME/.bun/bin:$PATH" bun run build
PATH="$HOME/.bun/bin:$PATH" bun run db:seed-dashboard
```
`db:seed-dashboard` **仅用于本地开发预览**。它会重置本地 SQLite 数据,并插入示例仓库/镜像/扫描/漏洞数据,以便在非空状态下直观地查看 `/dashboard`。
标签:API安全, API密钥, Bun, CISA项目, DevSecOps, GPT, JSON输出, SMTP, SQLite, Web截图, 上游代理, 代码安全, 仪表盘, 安全扫描, 容器安全, 数据保留, 时序注入, 漏洞可视化, 漏洞枚举, 漏洞管理, 网络安全, 自动化攻击, 邮件通知, 隐私保护