Nefrit0n/Red-Lycoris
GitHub: Nefrit0n/Red-Lycoris
开源的本地部署 ASOC 平台,用于聚合多种安全扫描工具的结果、去重并基于多源威胁情报计算优先级分数。
Stars: 0 | Forks: 0
本地部署 ASOC 平台,用于集中存储、去重和优先级排序漏洞。
## 这是什么
RedLycoris 接收 SAST/SCA/DAST/IaC/Secrets 扫描器的结果,根据 fingerprint 进行去重,从 NVD、EPSS、KEV、БДУ ФСТЭК、OSV 和 CWE 丰富数据,计算优先级分数,并提供 REST API + Web 界面。
**不运行扫描器。**仅接收扫描结果。
## 功能
**导入和规范化**
- 10 个内置解析器:SARIF 2.1.0、Trivy、Semgrep、gosec、Grype、ZAP、TruffleHog v3(NDJSON + array)、Gitleaks、Checkov、Generic JSON
- 自动识别输入文件格式
- 导入绑定到项目,并保留历史扫描链
**去重和历史**
- 基于 `cve + file_path + cwe + component + version` 的 SHA256 指纹
- 重复导入会增加 `times_seen` 并更新 `last_seen`,不会创建重复记录
- 每个 finding 的完整事件历史(状态、分配、评论)
**数据丰富(基于 Redis Streams 的异步管道)**
- NVD API 2.0、EPSS、CISA KEV、БДУ ФСТЭК、OSV、CWE MITRE、NVD CPE
- 三个 consumer worker,仅成功时 XACK,通过 `processPending()` 自动恢复挂起的消息
- 用于 air-gapped 部署的本地目录镜像
**优先级排序**
- 考虑 CVSS、EPSS、KEV、БДУ ФСТЭК、发布时间和 exposure 系数的公式
- 自动每 5 分钟更新的物化视图
**Findings 操作**
- 所有列表端点使用基于游标的分页(无 OFFSET)
- 分面筛选:severity、status、project、CVE、CWE、assignee、source_type、标签
- 批量操作:状态更改、关闭、重新打开、分配
- 保存的视图、评论、关闭原因
- 导出:CSV、XLSX、NDJSON、HTML
**多项目架构**
- Workspace → Projects → Findings
- 角色:Viewer、Triager、Project Admin、Global Admin
- 团队和组用于委托访问
- 每个项目范围受限的 API 令牌
**身份验证和审计**
- Cookie 会话(`rl_session`,`Secure` + `HttpOnly` + `SameSite=Strict`)
- 首次启动时创建 bootstrap admin + 强制密码更改
- `/api/v1/auth/login` 限流:每 IP+email 5 次/15 分钟 → HTTP 429 + `Retry-After`
- 审计日志记录所有更改的 diff,按月分区,通过 SSE 流式传输
**可观测性**
- `/healthz`(存活)、`/readyz`(就绪 — postgres + redis)、`/metrics`(Prometheus 文本格式)
- 结构化 JSON 日志(`slog`)
- 优雅关闭:SIGTERM → 排空 HTTP(15 秒)→ XACK 当前消息 → 关闭连接池
**UI**
- React 18 + TypeScript strict + TanStack Table/Query/Virtual + shadcn/ui + Tailwind CSS
- 10 万+ 行的虚拟化列表
- 完全中文界面
## 架构
```
Сканер ──multipart──► POST /api/v1/import
│
▼
Парсер (auto-detect)
│
▼
Дедупликация по fingerprint
│
┌──────┴──────┐
│ │
новый дубль
▼ ▼
INSERT UPDATE last_seen
times_seen++
│
▼
Redis Streams ──► Enrichment workers ×3
├─ NVD ├─ KEV
├─ EPSS ├─ БДУ ФСТЭК
├─ OSV └─ CWE / CPE
│
▼
Priority Score (materialized view, refresh 5m)
│
▼
REST API ──► React UI
```
详见 [docs/architecture.md](docs/architecture.md)。
### 技术栈
| 层级 | 技术 |
|------|------------|
| 后端 | Go 1.22+、chi router、pgx/v5、golang-migrate、slog、bcrypt、go-redis |
| 数据库 | PostgreSQL 16(分区、物化视图)|
| 缓存/队列 | Redis 7(Streams + AOF)|
| 前端 | React 18、TypeScript、Vite、Tailwind CSS、TanStack Table/Query/Virtual、Zustand、shadcn/ui |
| 部署 | Docker Compose(多阶段构建、非 root 用户)|
## 快速开始
```
git clone https://github.com/nefrit0n/red-lycoris.git
cd red-lycoris
cp env.example .env
# 必须设置: POSTGRES_PASSWORD, BOOTSTRAP_ADMIN_EMAIL, BOOTSTRAP_ADMIN_PASSWORD
./scripts/build.sh
docker compose up -d
```
打开 [http://localhost:3000](http://localhost:3000)。
登录使用 `BOOTSTRAP_ADMIN_EMAIL` / `BOOTSTRAP_ADMIN_PASSWORD` 的值。首次登录时如果 `BOOTSTRAP_ADMIN_FORCE_PASSWORD_CHANGE=true` 会要求更改密码。
### Make 命令
```
make dev # docker compose up --build (foreground)
make dev-d # то же, в фоне
make prod # production-overlay (nginx, закрытые порты БД)
make migrate # применить миграции вручную
make seed # сгенерировать тестовые данные
make sync # ручной запуск всех источников обогащения
make logs # tail логов всех сервисов
make logs-api # только backend
make stop # остановить (данные сохраняются)
make clean # остановить + удалить volume-ы (данные ПОТЕРЯЮТСЯ)
make help # список всех целей
```
## 生产环境部署
```
./scripts/build.sh
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```
production-overlay 与 dev 的区别:
- 不对外暴露 PostgreSQL 和 Redis 端口
- 前端在 production 阶段构建(使用 nginx 而非 Vite)
- 不绑定挂载源码
- 增加资源限制
- `ENV=production`(默认启用 `Secure` cookie)
对外发布前务必配置:`COOKIE_SECURE=true`、明确的 `CORS_ORIGINS` 列表、`TRUST_PROXY=true`(如果放在 reverse proxy 后)、唯一密码。检查清单见 [docs/security-model.md](docs/security-model.md)。
## 支持的扫描器






| 扫描器 | 格式 | 解析器 |
|--------|--------|--------|
| Semgrep / OpenGrep | SARIF 2.1.0 / native JSON | `SARIFParser`、`SemgrepParser` |
| Trivy | JSON | `TrivyParser` |
| gosec | JSON / SARIF | `GosecParser` |
| Grype | JSON | `GrypeParser` |
| OWASP ZAP | JSON | `ZAPParser` |
| TruffleHog v3 | JSON / NDJSON | `TruffleHogParser` |
| Gitleaks | JSON | `GitleaksParser` |
| Checkov | JSON | `CheckovParser` |
| 任意 | Generic JSON | `GenericParser` |
格式自动检测(`internal/parser/detect.go`)。要添加解析器 — 实现 `parser.Parser` 接口并在 `parsers` 中注册。
## 数据来源







| 数据库 | 频率 | 模式 |
|------|---------|-------|
| NVD API 2.0 | 每 2 小时(增量)| online / 本地镜像 |
| EPSS(Cyentia)| 每日 | daily CSV gzip |
| CISA KEV | 每 6 小时 | JSON feed |
| БДУ ФСТЭК | 每周 | ZIP 中的 XML |
| OSV | 每日 | GCS bucket ZIP |
| CWE(MITRE)| 每月 | ZIP 中的 XML |
| NVD CPE | 每周 | JSON API |
所有来源通过 Redis Streams consumer-group 在后台运行。无外部网络时使用之前加载的数据。手动运行任何来源 — `POST /api/v/enrichment/sync/{source}` 或 `make sync`。
允许列表的 IP/主机:[docs/network_requirements.md](docs/network_requirements.md)。
## 优先级排序
```
priority_score = cvss_base × 0.30
+ epss × 100 × 0.25
+ (10 if kev else 0) × 0.20
+ (5 if bdu else 0) × 0.10
+ recency × 0.10
+ exposure × 0.05
```
其中 `recency = 10 × exp(-days_since_published / 365)`,`exposure` — 每个项目可配置的系数。
实现见 `internal/domain/scoring.go`。评分存储在每 5 分钟自动更新的物化视图中。
## 去重
```
fingerprint = SHA256(
lower(cve_id || "") +
lower(file_path || "") +
str(cwe_id || 0) +
lower(component || "") +
lower(component_version || "")
)
```
指纹匹配时:
- `last_seen = now()`
- `times_seen += 1`
- **不**创建新记录
## API
REST + OpenAPI 3.1。dev 模式下可访问交互式文档:[http://localhost:8080/api/docs](http://localhost:8080/api/docs)。
```
# 版本(公共端点)
curl http://localhost:8080/api/v1/version
# 导入扫描结果
curl -X POST http://localhost:8080/api/v1/import \
-H "Cookie: rl_session=
" \
-F "file=@trivy-results.json" \
-F "project_id="
# 发现列表
curl "http://localhost:8080/api/v1/findings?severity=high,critical&status=open&limit=50&sort=-priority_score" \
-H "Cookie: rl_session="
# 导出
curl "http://localhost:8080/api/v1/findings/export.xlsx?project_id=" \
-H "Cookie: rl_session=" -o findings.xlsx
```
所有响应格式:
```
{ "data": { ... }, "meta": { "total": 15000, "next_cursor": "...", "has_more": true } }
```
所有列表端点使用基于游标的分页。无 OFFSET。
## 配置
所有参数通过环境变量配置。完整列表及说明见 [docs/configuration.md](docs/configuration.md)。
生产环境最小配置:
| 变量 | 必填 | 描述 |
|------------|-------------|----------|
| `POSTGRES_PASSWORD` | 是 | 数据库密码(最少 20 字符)|
| `BOOTSTRAP_ADMIN_EMAIL` | 是 | 第一个管理员的邮箱 |
| `BOOTSTRAP_ADMIN_PASSWORD` | 是 | 第一个管理员的密码 |
| `BOOTSTRAP_ADMIN_FORCE_PASSWORD_CHANGE` | 推荐 | `true` — 首次登录时要求更改密码 |
| `COOKIE_SECURE` | HTTPS 时 | `true` |
| `CORS_ORIGINS` | 对外发布时 | 明确的 origin 列表(不用 `*`)|
| `TRUST_PROXY` | reverse proxy 后 | `true` 以解析 `X-Forwarded-For` |
| `NVD_API_KEY` | 否 | 将 NVD rate limit 从 5 提高到 50 req/30s |
| `SESSION_DURATION` | 否 | 默认 `168h` |
## 开发
```
# 仅基础设施
docker compose up -d postgres redis
# Backend
cd backend && go run ./cmd/server
# Frontend (Vite dev server)
cd frontend && npm install && npm run dev
```
### CLI 工具
| 命令 | 用途 |
|---------|-----------|
| `go run ./backend/cmd/server` | API 服务器 |
| `go run ./backend/cmd/admin create-user` | 创建用户 |
| `go run ./backend/cmd/admin reset-password` | 重置密码 |
| `go run ./backend/cmd/admin list-users` | 用户列表 |
| `go run ./backend/cmd/admin deactivate` | 停用用户 |
| `go run ./backend/cmd/seed` | 生成测试数据 |
| `go run ./backend/cmd/loadtest` | 负载测试 |
### 仓库结构
```
.
├── backend/ # Go API
│ ├── cmd/{server,admin,seed,loadtest}/
│ ├── internal/
│ │ ├── api/ # chi handlers + middleware
│ │ ├── auth/ # сессии, argon2id
│ │ ├── audit/ # audit log + SSE
│ │ ├── domain/ # бизнес-логика, scoring, dedup
│ │ ├── storage/ # pgx/v5 SQL (без ORM)
│ │ ├── parser/ # парсеры сканеров
│ │ ├── enrichment/ # Redis Streams workers
│ │ ├── export/ # CSV/XLSX/NDJSON/HTML
│ │ ├── observability/ # health + Prometheus metrics
│ │ └── version/ # build-info
│ └── migrations/ # 030 SQL-миграций (golang-migrate)
├── frontend/ # React 18 + TS + Vite
│ └── src/{api,pages,components,store,hooks,types}/
├── docs/ # архитектура, deployment, ops, релиз-ноты
├── deployments/ # альтернативный prod-overlay
├── ops/backup/ # скрипты бэкапа
├── scripts/ # build.sh, seed.sh
├── docker-compose.yml
├── docker-compose.prod.yml
├── env.example
└── Makefile
```
## 测试
```
cd backend && go test ./...
cd frontend && npm run lint && npm test
```
CI 在每个 PR 上运行:`go vet`、`go test`、`eslint`、`vitest`、构建两个镜像。配置见 [.github/workflows/ci.yml](.github/workflows/ci.yml)。
## 文档
- [部署](docs/deployment.md)
- [配置](docs/configuration.md)
- [架构](docs/architecture.md)
- [安全模型](docs/security-model.md)
- [网络要求(允许列表)](docs/network_requirements.md)
- [GitLab CI/CD 集成](docs/gitlab-ci.md)
- [备份](docs/ops/backup-restore.md)
- [迁移](docs/ops/migrations.md)
- [可观测性](docs/ops/observability.md)
- [已知问题](docs/KNOWN_ISSUES.md)
- [CHANGELOG](CHANGELOG.md)
- [0.1.0b 发布说明](docs/release-notes/0.1.0b.md)
## 要求
- Docker 24+ 和 Docker Compose v2
- 最低 4 GB RAM,生产环境建议 8 GB
- 20 GB 可用磁盘空间(PostgreSQL + Redis AOF + 本地目录镜像)
- 网络访问数据来源 — 或为 air-gapped 安装预加载数据
## 许可证
Apache 2.0 — 见 [LICENSE](LICENSE)。标签:Air-gapped, Angular, ASOC, DAST, DevSecOps, Docker, EPSS, EVTX分析, FTP漏洞扫描, Gitleaks, Go, GPT, Grype, IaC安全, NVD, On-premise, OSV, PostgreSQL, React, Redis, REST API, Ruby工具, SARIF, SAST, Semgrep, Syscalls, Vercel, Web界面, WordPress安全扫描, 上游代理, 云安全监控, 威胁情报, 安全编排, 安全防御评估, 开发者工具, 恶意软件分析, 搜索引擎查询, 日志审计, 测试用例, 漏洞优先级, 漏洞去重, 漏洞管理, 漏洞聚合, 盲注攻击, 离线部署, 私有化部署, 请求拦截, 防御规避, 静态分析