tamasmrtn/trivyal

GitHub: tamasmrtn/trivyal

一款面向家庭实验室和小型 Docker 环境的轻量级自托管容器漏洞扫描器,采用 Hub-Agent 架构,通过 Trivy 扫描运行时容器并聚合展示结果。

Stars: 0 | Forks: 0

Trivyal

一个轻量级、自托管的容器漏洞扫描器,采用 Hub-Agent 模型,由 Trivy 提供支持。

Trivyal 专为家庭实验室和小型多服务器 Docker 环境设计。一个轻量级的 Agent 运行在每台主机上,使用 Trivy 扫描本地容器,并将结果发送到中央 Hub,Hub 聚合所有数据并在单一 UI 中展示。 ## 替代方案 **[Harbor](https://goharbor.io/)** 是一个已从 CNCF 毕业的容器镜像仓库,内置漏洞扫描、镜像签名和基于角色的访问控制。如果你需要一个私有镜像仓库,请使用它——扫描功能是附带的 bonus。它在镜像仓库层面运行(在推送时扫描镜像),而不是在运行时层面,因此它无法检测到使用在新 CVE 披露之前推送的镜像运行的容器。 **[DefectDojo](https://www.defectdojo.org/)** 是一个功能齐全的 DevSecOps 漏洞管理平台。它接收来自多种扫描器(包括 Trivy)的发现结果,对其进行去重,跟踪修复进度,生成报告,并与问题跟踪器和 CI 流水线集成。当你需要在多个团队、产品和扫描器类型之间建立统一的安全管理程序时使用它——运行它需要投入大量的运维精力。 **在以下情况请使用 Trivyal**:你运行的是家庭实验室或小型多服务器 Docker 环境,并且需要一个单一的轻量级工具来告诉你当前主机上正在运行哪些漏洞——无需镜像仓库、无需流水线、无需专门的安全团队。Trivyal 专注于做一件事:通过 Docker socket 发现实际运行的内容,使用 Trivy 进行扫描,并将新发现呈现给你。 ## 功能特性 ### Hub - 仪表盘显示所有已连接的 Agent 及其状态(在线 / 离线 / 扫描中) - 跨所有主机的聚合漏洞视图 —— 可按严重程度(Critical, High, Medium, Low, Unknown)过滤 - 针对单个主机和单个容器的深入详情 - 发现时间线 —— 跟踪 CVE 出现和解决的时间 - 扫描间的差异视图 —— 高亮显示新增和已修复的发现 - 风险接受 —— 将某个发现标记为已接受,并附上原因和过期日期 - 针对单个发现的误报标记 - 每台主机的完整扫描历史日志 - 发现新的 Critical/High 级别漏洞时的 Webhook 通知(Slack, Discord, Ntfy) - Agent 管理 UI —— 添加、移除和查看 Agent;复制粘贴 Docker Compose 片段以快速部署 - 深色模式 UI(默认为深色,可切换) - 单一管理员用户,支持基于 Token 的 API 访问 ### Agent - 通过 Docker socket 自动发现所有运行中的容器 - 根据可配置的计划(默认:每晚)对每个容器进行 Trivy 镜像扫描 - 支持从 Hub 触发按需扫描 - 通过经过身份验证的 WebSocket 连接将结果发送到 Hub - 在本地缓存最后一次扫描结果,以便在 Hub 暂时无法访问时保持弹性 - 自我报告主机元数据(主机名、Docker 版本、操作系统、Agent 版本) - 轻量级 —— 作为单个 Docker 容器运行,以只读方式挂载 Docker socket ## 架构 Trivyal 采用 Hub-Agent 模型。Hub 是聚合扫描结果并提供 UI 的中央服务器。Agent 运行在每台 Docker 主机上,执行扫描,并通过持久化、经过身份验证的 WebSocket 连接回调 Hub。 ``` ┌─────────────────────────────────┐ ┌──────────────────────────────────┐ │ Hub Server │ │ Agent Host │ │ │ │ │ │ ┌─────────────────────────┐ │ │ ┌───────────────────────────┐ │ │ │ React UI │ │ │ │ Trivyal Agent │ │ │ │ (shadcn/ui dark mode) │ │ │ │ (Python) │ │ │ └──────────┬──────────────┘ │ │ │ │ │ │ │ HTTP │ │ │ - Docker socket listener │ │ │ ┌──────────▼──────────────┐ │ │ │ - Trivy runner │ │ │ │ FastAPI Hub │ │ │ │ - Result cache │ │ │ │ (Python) │◄───┼───────┼──│ - WebSocket client │ │ │ │ │ │ WSS │ └───────────┬───────────────┘ │ │ │ - Agent manager │ │ │ │ │ │ │ - Scan aggregator │ │ │ /var/run/docker.sock (ro) │ │ │ - Auth / token mgmt │ │ └──────────────────────────────────┘ │ │ - Notification sender │ │ │ └──────────┬──────────────┘ │ │ │ │ │ ┌──────────▼──────────────┐ │ │ │ SQLite DB │ │ │ └─────────────────────────┘ │ └─────────────────────────────────┘ ``` ### 技术栈 | 层级 | 选型 | |---|---| | Hub 后端 | Python 3.14 + FastAPI | | Hub 数据库 | SQLite via SQLModel | | Hub 前端 | React + shadcn/ui + Tailwind CSS | | Agent | Python 3.14 | | 包管理 | uv | | 扫描器 | Trivy (CLI, 由 agent 调用) | | 认证 | Ed25519 keypair + token (PyNaCl) | | 通信 | WebSocket (持久化,允许 Hub 发起扫描触发) | | 容器化 | Docker Compose | ### 注册流程 当你在 UI 中添加 Agent 时,Hub 会生成一个注册 Token 和一个 Ed25519 密钥对。你使用该 Token、Hub URL 和 Hub 公钥部署 Agent。首次连接时,Hub 验证 Token,Agent 通过签名质询验证 Hub 的身份。握手完成后,Agent 的机器指纹(派生自 `/etc/machine-id`)会被存储 —— 将该 Token 锁定到原始主机。 ## 快速开始 ### 前置条件 - 所有主机上均已安装 Docker 和 Docker Compose - Hub 主机必须能被所有 Agent 主机通过 TCP 访问(默认端口 `8099`) ### 1. 部署 Hub 在 Hub 主机上,克隆仓库并创建你的 `.env`: ``` cp .env.example .env ``` 编辑 `.env` 并至少设置: ``` TRIVYAL_SECRET_KEY= TRIVYAL_ADMIN_PASSWORD= ``` 构建并启动 Hub: ``` docker compose -f docker-compose.hub.yml up --build -d ``` 在浏览器中打开 `http://:8099` 并使用你的管理员凭据登录。 ### 2. 添加 Agent 1. 在 UI 中进入 **Agents** 并点击 **Add Agent**。 2. 复制对话框中显示的 **Token** 和 **Hub Public Key**。 3. 在 Agent 主机上,克隆仓库并创建一个 `.env`: ``` TRIVYAL_HUB_URL=ws://:8099 AGENT_TOKEN= AGENT_HUB_KEY= ``` 4. 构建并启动 Agent: ``` docker compose -f docker-compose.agent.yml up --build -d ``` Agent 将在几秒钟内出现在 Hub UI 中并显示为在线。扫描将在配置的计划时间运行(默认:每晚 02:00),或者你可以立即从 **Agents** 页面触发一次扫描。 ## 环境变量 所有变量均使用 `TRIVYAL_` 前缀,并可从环境变量或 `.env` 文件中读取。复制 `.env.example` 即可开始。 ### Hub | 变量 | 必填 | 默认值 | 描述 | |---|---|---|---| | `TRIVYAL_SECRET_KEY` | **yes** | — | 用于签名 Token 的长随机字符串。使用 `openssl rand -hex 32` 生成。 | | `TRIVYAL_ADMIN_PASSWORD` | no | `admin` | Web UI 管理员登录密码。请修改此默认值。 | | `TRIVYAL_DATA_DIR` | no | `/app/data` | 存储 SQLite 数据库的目录。 | | `TRIVYAL_DATABASE_URL` | no | derived | 完整的 SQLite 连接 URL。如果设置,将覆盖 `TRIVYAL_DATA_DIR`。 | | `TRIVYAL_HOST` | no | `0.0.0.0` | 绑定的网络接口。 | | `TRIVYAL_PORT` | no | `8099` | 监听的端口。 | | `TRIVYAL_STATIC_DIR` | no | `/app/static` | 包含构建好的 React UI 的目录。在 Docker 中自动存在;在开发模式下不使用。 | ### Agent | 变量 | 必填 | 默认值 | 描述 | |---|---|---|---| | `TRIVYAL_HUB_URL` | **yes** | `ws://localhost:8099` | Hub 的 WebSocket URL。在生产环境中请使用 `wss://`。 | | `TRIVYAL_TOKEN` | **yes** | — | 在 Hub UI 中生成的注册 Token (Agents → Add Agent)。 | | `TRIVYAL_KEY` | **yes** | — | 在 Hub UI 中与 Token 一起显示的 Hub Ed25519 公钥。 | | `TRIVYAL_SCAN_SCHEDULE` | no | `0 2 * * *` | 计划扫描的 Cron 表达式(默认:每晚 02:00)。 | | `TRIVYAL_DATA_DIR` | no | `/app/data` | 本地扫描结果缓存的目录。 | | `TRIVYAL_HEARTBEAT_INTERVAL` | no | `30` | 向 Hub 发送心跳消息的间隔秒数。 | | `TRIVYAL_RECONNECT_DELAY` | no | `10` | 连接断开后等待重新连接的秒数。 | ### Docker Compose | 变量 | 默认值 | 描述 | |---|---|---| | `AGENT_TOKEN` | — | 作为 `TRIVYAL_TOKEN` 传递给 `docker-compose.hub.yml` 中位于同一主机的 Agent。 | | `AGENT_HUB_KEY` | — | 作为 `TRIVYAL_KEY` 传递给 `docker-compose.hub.yml` 中位于同一主机的 Agent。 | ### 开发设置 本仓库使用 [uv](https://docs.astral.sh/uv/) 进行 Python 依赖管理。 ``` trivyal/ ├── hub/ # Hub service (FastAPI) — uv project ├── agent/ # Agent service (Python) — uv project ├── ui/ # React frontend (Vite + TypeScript) └── docs/ # Architecture and guides ``` **安装所有依赖(包括 pre-commit hooks):** ``` make init ``` 这将安装 [pre-commit](https://pre-commit.com/) 作为 uv 工具,并设置用于 linting (ruff)、格式化、安全扫描 (bandit) 和 lockfile 验证的 git hooks。手动运行所有 hooks: ``` make lint ``` **以开发模式运行服务:** ``` make dev-hub make dev-agent make dev-ui ``` **运行测试:** ``` make test # all services make test-hub make test-agent make test-ui ``` ## 灵感 Hub-Agent 模型和整体 UX 理念受到了 [Beszel](https://github.com/henrygd/beszel) 的启发,这是一个轻量级的服务器监控工具。推荐使用! ## 许可证 MIT
标签:Claude, CVE检测, DevSecOps, Docker, Go语言, GPT, Hub-Agent架构, LangChain, Web截图, 上游代理, 多服务器管理, 安全仪表盘, 安全防御评估, 家庭实验室, 容器安全, 开源安全工具, 漏洞管理, 程序破解, 聚合展示, 自托管, 请求拦截, 轻量级, 逆向工程平台, 镜像审计