kamalvasvani1989-coder/Container_Vulnerabilty_Scanner
GitHub: kamalvasvani1989-coder/Container_Vulnerabilty_Scanner
一款围绕 Trivy 构建的容器镜像漏洞扫描编排工具,通过可配置的策略阈值和退出码契约在 CI/CD 流水线中实现自动化的安全拦截。
Stars: 0 | Forks: 0
# 容器镜像漏洞扫描器
一款 **安全左移 (shift-left security)** 工具,用于扫描容器镜像中的已知漏洞,并在不安全的镜像进入生产环境之前拦截构建流水线。该项目通过围绕 [Trivy](https://github.com/aquasecurity/trivy) 进行编排来构建,而不是重新发明扫描器 —— 因此构建快速、运行成本低,且与真实的 CI/CD 安全实践保持一致。
## 目录
- [为什么开发这个项目](#why-this-project)
- [核心概念](#key-concepts)
- [系统架构](#system-architecture)
- [扫描与拦截流程](#scan--gate-flow)
- [技术栈](#technology-stack)
- [入门指南](#getting-started)
- [使用方法](#usage)
- [退出码](#exit-codes)
- [调整策略拦截](#tuning-the-policy-gate)
- [工作原理](#how-it-works)
- [路线图](#roadmap)
- [项目结构](#project-structure)
## 为什么开发这个项目
容器镜像由许多层构建而成,每一层都可能包含带有已发布 CVE(常见漏洞和披露)的过时软件包。将这些镜像发布到生产环境会使整个系统暴露在风险中。这款扫描器能够:
- **检测**任何容器镜像中的已知漏洞。
- 根据可配置的策略**判定**通过或失败。
- 当镜像风险过高时,自动**拦截**流水线。
- **报告**结果,以便人工和仪表板采取相应措施。
以下两项原则驱动了该设计:
- **封装,而非重建。** Trivy 是经过验证的扫描引擎。其核心价值在于围绕它的编排层 —— 运行扫描、解读结果并执行策略。
- **垂直切片优先。** 在扩展到报告、仪表板和例外处理之前,先跑通一条轻量级的端到端路径(推送 → 扫描 → 拦截)。
## 核心概念
| 术语 | 含义 |
|------|---------|
| **策略拦截 (Policy Gate)** | 通过/失败规则。按严重程度统计漏洞,并与配置的阈值进行比较。 |
| **工具失败 vs. 策略失败** | *崩溃*(无法扫描)的处理方式与 *拦截*(扫描成功,但漏洞过多)完全不同。这两者绝对不能混淆。 |
| **严重性阈值** | 每个严重级别所允许的最大数量(例如 `CRITICAL: 0`, `HIGH: 10`)。超出该阈值将导致构建失败。 |
| **退出码契约** | 脚本返回的数字信号,以便 CI/CD 无需解析文本即可了解发生了什么。 |
## 系统架构
各个组件的连接方式 —— 从开发人员提交代码,经过 Sprint 1 编排层,到三种可能的结果。虚线框内是计划在后续迭代中实现的组件。

开发人员推送代码后,镜像将被构建,随后 `scanner.py` 接管流程:它会从 `policy.yaml` 读取阈值,对该镜像运行 Trivy,并将结果输入到策略拦截器中。拦截器会准确生成三种退出码之一 —— 通过、策略失败或工具错误 —— 这正是 CI/CD 在下一个 sprint 中要据此执行操作的依据。
## 扫描与拦截流程
单次扫描的运行时序列 —— `scanner.py` 执行的四项任务,以及每种结果如何映射到特定的退出码。
```
flowchart TD
Start([Run: python scanner.py IMAGE]) --> Load[Load policy.yaml]
Load --> PolicyOK{Policy
readable?} PolicyOK -->|No| Err[/Exit 2 — TOOL ERROR/] PolicyOK -->|Yes| RunTrivy[Run Trivy
trivy image --format json --quiet] RunTrivy --> TrivyOK{Trivy ran
successfully?} TrivyOK -->|No| Err TrivyOK -->|Yes| Parse[Parse JSON
walk Results then Vulnerabilities] Parse --> Count[Count vulnerabilities
grouped by severity] Count --> Gate{Any severity
exceeds
threshold?} Gate -->|Yes| Fail[/Exit 1 — POLICY FAIL
block the build/] Gate -->|No| Pass[/Exit 0 — PASS
build continues/] Parse --> Report[Print summary table] Report --> Gate style Err fill:#f8d7da,stroke:#a71d2a style Fail fill:#fff3cd,stroke:#d39e00 style Pass fill:#d4edda,stroke:#2d7a3e style Start fill:#e8f4ea,stroke:#2d7a3e ``` 特意区分退出码 `1` 和 `2` 的原因是:**损坏的扫描器绝对不能看起来像是构建通过**,而且**漏洞拦截也绝对不能看起来像是崩溃**。 ## 技术栈 | 层级 | 工具 | 状态 | |-------|------|--------| | 扫描引擎 | **Trivy** | Sprint 1 ✅ | | 编排 | **Python 3.11+** | Sprint 1 ✅ | | 策略配置 | **YAML** (PyYAML) | Sprint 1 ✅ | | CI/CD 拦截 | **GitHub Actions** → **Jenkins** | Later | | 通知 | **Slack webhooks** | Later | | 报告 | **Jinja2 + WeasyPrint** | Later | | 指标与仪表板 | **Prometheus Pushgateway + Grafana** | Later | | 存储 | **SQLite → PostgreSQL** | Later | | 环境 | **WSL2 + Docker Desktop** | Setup ✅ | ## 入门指南 ### 前置条件 完整的环境设置(WSL2、Docker、Python、Trivy、Git)已在单独的设置指南中介绍。简而言之,你需要安装 Trivy 并确保 Docker 正在运行。 ### 安装依赖 在项目文件夹内,激活你的虚拟环境后(你的命令行提示符应显示 `(.venv)`): ``` pip install pyyaml ``` 这是唯一的依赖项。其他所有内容均来自 Python 标准库和 Trivy 本身。 ## 使用方法 对镜像运行扫描: ``` python scanner.py python:3.9-slim ``` 使用特定的策略文件: ``` python scanner.py python:3.9-slim --policy policy.yaml ``` 运行后检查退出码: ``` python scanner.py python:3.9-slim echo "exit code: $?" ``` ## 退出码 | 代码 | 含义 | 触发条件 | |------|---------|------| | `0` | **PASS** (通过) | 扫描成功运行,满足策略 | | `1` | **POLICY FAIL** (策略失败) | 扫描成功运行,但漏洞过多 —— 拦截构建 | | `2` | **TOOL ERROR** (工具错误) | 无法扫描或无法读取策略 —— 发出警报 | CI/CD 会读取此代码,以决定是继续执行、拦截还是发出警报。 ## 调整策略拦截 拦截逻辑位于 `policy.yaml` 中: ``` thresholds: CRITICAL: 0 HIGH: 10 ``` 当某个严重级别的漏洞**数量超过限制时,将导致构建失败。** 因此,在设置 `HIGH: 10` 的情况下,如果扫描恰好发现 10 个 HIGH 漏洞,它依然会通过;如果是 11 个则会失败。`CRITICAL: 0` 表示任何严重漏洞都会导致失败 —— 零容忍。 ### 临时提高限制阈值 当应用程序的 HIGH 漏洞数量超过允许范围,且上游修复尚未发布时,可以提高该数值以解除构建拦截 —— 并说明原因: ``` thresholds: CRITICAL: 0 HIGH: 20 # raised from 10 for app-x, pending upstream patch; # set a review date and tighten again once fixed ``` 然后使用清晰的信息提交,这样 Git 历史记录就会成为你的审计追踪: ``` git add policy.yaml git commit -m "Raise HIGH gate to 20 for app-x pending upstream patch" ``` ## 工作原理 `scanner.py` 按顺序执行四项任务: 1. **运行 Trivy** —— 调用 `trivy image --format json --quiet` 并从 stdout 获取 JSON 输出。此处特意*不*使用 Trivy 自带的 `--exit-code` 参数,这样 Trivy 返回非零退出码就明确代表工具自身失败,而不是发现了漏洞。
2. **解析** —— 遍历 `Results[].Vulnerabilities[]`,对于不存在 vulnerabilities 键的干净层级会进行容错处理。
3. **应用拦截** —— 按严重程度统计漏洞,并将其与对应的阈值进行比较。
4. **报告** —— 打印汇总表并返回退出码。
## 路线图
该项目分六个 sprint 构建(每个约 20 小时),每个 sprint 会为这个可用的垂直切片增加一项新功能。
```
flowchart LR
S1[Sprint 1
Python
Orchestration] --> S2[Sprint 2
CI/CD
Gating] S2 --> S3[Sprint 3
Reporting &
Notifications] S3 --> S4[Sprint 4
Dashboard] S4 --> S5[Sprint 5
Exceptions &
Customization] S5 --> S6[Sprint 6
Documentation
& Testing] style S1 fill:#d4edda,stroke:#2d7a3e,stroke-width:2px style S2 fill:#f5f5f5,stroke:#999 style S3 fill:#f5f5f5,stroke:#999 style S4 fill:#f5f5f5,stroke:#999 style S5 fill:#f5f5f5,stroke:#999 style S6 fill:#f5f5f5,stroke:#999 ``` | Sprint | 重点 | 新增内容 | |--------|-------|------| | **1** | 编排层 | 运行 Trivy,解析,执行通过/失败拦截 ✅ | | **2** | CI/CD 拦截 | 将拦截器接入 GitHub Actions(后续接入 Jenkins) | | **3** | 报告与通知 | PDF/HTML 报告(Jinja2 + WeasyPrint),Slack 警报 | | **4** | 仪表板 | 将指标推送到 Prometheus,在 Grafana 中进行可视化 | | **5** | 例外与自定义 | 支持自动过期的按 CVE 例外处理 | | **6** | 文档与测试 | 强化、测试覆盖率、最终文档 | ## 项目结构 ``` vuln-scanner/ ├── scanner.py # The wrapper: run Trivy, parse, gate, report ├── policy.yaml # Tunable gate thresholds ├── README.md # This file ├── docs/ │ └── architecture.svg # System architecture diagram ├── .gitignore # Ignores .venv/ and result.json └── .venv/ # Virtual environment (not committed) ``` *作为个人学术项目构建,旨在展示如何通过注重成本效益的工具实现安全左移的容器安全。*
readable?} PolicyOK -->|No| Err[/Exit 2 — TOOL ERROR/] PolicyOK -->|Yes| RunTrivy[Run Trivy
trivy image --format json --quiet] RunTrivy --> TrivyOK{Trivy ran
successfully?} TrivyOK -->|No| Err TrivyOK -->|Yes| Parse[Parse JSON
walk Results then Vulnerabilities] Parse --> Count[Count vulnerabilities
grouped by severity] Count --> Gate{Any severity
exceeds
threshold?} Gate -->|Yes| Fail[/Exit 1 — POLICY FAIL
block the build/] Gate -->|No| Pass[/Exit 0 — PASS
build continues/] Parse --> Report[Print summary table] Report --> Gate style Err fill:#f8d7da,stroke:#a71d2a style Fail fill:#fff3cd,stroke:#d39e00 style Pass fill:#d4edda,stroke:#2d7a3e style Start fill:#e8f4ea,stroke:#2d7a3e ``` 特意区分退出码 `1` 和 `2` 的原因是:**损坏的扫描器绝对不能看起来像是构建通过**,而且**漏洞拦截也绝对不能看起来像是崩溃**。 ## 技术栈 | 层级 | 工具 | 状态 | |-------|------|--------| | 扫描引擎 | **Trivy** | Sprint 1 ✅ | | 编排 | **Python 3.11+** | Sprint 1 ✅ | | 策略配置 | **YAML** (PyYAML) | Sprint 1 ✅ | | CI/CD 拦截 | **GitHub Actions** → **Jenkins** | Later | | 通知 | **Slack webhooks** | Later | | 报告 | **Jinja2 + WeasyPrint** | Later | | 指标与仪表板 | **Prometheus Pushgateway + Grafana** | Later | | 存储 | **SQLite → PostgreSQL** | Later | | 环境 | **WSL2 + Docker Desktop** | Setup ✅ | ## 入门指南 ### 前置条件 完整的环境设置(WSL2、Docker、Python、Trivy、Git)已在单独的设置指南中介绍。简而言之,你需要安装 Trivy 并确保 Docker 正在运行。 ### 安装依赖 在项目文件夹内,激活你的虚拟环境后(你的命令行提示符应显示 `(.venv)`): ``` pip install pyyaml ``` 这是唯一的依赖项。其他所有内容均来自 Python 标准库和 Trivy 本身。 ## 使用方法 对镜像运行扫描: ``` python scanner.py python:3.9-slim ``` 使用特定的策略文件: ``` python scanner.py python:3.9-slim --policy policy.yaml ``` 运行后检查退出码: ``` python scanner.py python:3.9-slim echo "exit code: $?" ``` ## 退出码 | 代码 | 含义 | 触发条件 | |------|---------|------| | `0` | **PASS** (通过) | 扫描成功运行,满足策略 | | `1` | **POLICY FAIL** (策略失败) | 扫描成功运行,但漏洞过多 —— 拦截构建 | | `2` | **TOOL ERROR** (工具错误) | 无法扫描或无法读取策略 —— 发出警报 | CI/CD 会读取此代码,以决定是继续执行、拦截还是发出警报。 ## 调整策略拦截 拦截逻辑位于 `policy.yaml` 中: ``` thresholds: CRITICAL: 0 HIGH: 10 ``` 当某个严重级别的漏洞**数量超过限制时,将导致构建失败。** 因此,在设置 `HIGH: 10` 的情况下,如果扫描恰好发现 10 个 HIGH 漏洞,它依然会通过;如果是 11 个则会失败。`CRITICAL: 0` 表示任何严重漏洞都会导致失败 —— 零容忍。 ### 临时提高限制阈值 当应用程序的 HIGH 漏洞数量超过允许范围,且上游修复尚未发布时,可以提高该数值以解除构建拦截 —— 并说明原因: ``` thresholds: CRITICAL: 0 HIGH: 20 # raised from 10 for app-x, pending upstream patch; # set a review date and tighten again once fixed ``` 然后使用清晰的信息提交,这样 Git 历史记录就会成为你的审计追踪: ``` git add policy.yaml git commit -m "Raise HIGH gate to 20 for app-x pending upstream patch" ``` ## 工作原理 `scanner.py` 按顺序执行四项任务: 1. **运行 Trivy** —— 调用 `trivy image --format json --quiet
Python
Orchestration] --> S2[Sprint 2
CI/CD
Gating] S2 --> S3[Sprint 3
Reporting &
Notifications] S3 --> S4[Sprint 4
Dashboard] S4 --> S5[Sprint 5
Exceptions &
Customization] S5 --> S6[Sprint 6
Documentation
& Testing] style S1 fill:#d4edda,stroke:#2d7a3e,stroke-width:2px style S2 fill:#f5f5f5,stroke:#999 style S3 fill:#f5f5f5,stroke:#999 style S4 fill:#f5f5f5,stroke:#999 style S5 fill:#f5f5f5,stroke:#999 style S6 fill:#f5f5f5,stroke:#999 ``` | Sprint | 重点 | 新增内容 | |--------|-------|------| | **1** | 编排层 | 运行 Trivy,解析,执行通过/失败拦截 ✅ | | **2** | CI/CD 拦截 | 将拦截器接入 GitHub Actions(后续接入 Jenkins) | | **3** | 报告与通知 | PDF/HTML 报告(Jinja2 + WeasyPrint),Slack 警报 | | **4** | 仪表板 | 将指标推送到 Prometheus,在 Grafana 中进行可视化 | | **5** | 例外与自定义 | 支持自动过期的按 CVE 例外处理 | | **6** | 文档与测试 | 强化、测试覆盖率、最终文档 | ## 项目结构 ``` vuln-scanner/ ├── scanner.py # The wrapper: run Trivy, parse, gate, report ├── policy.yaml # Tunable gate thresholds ├── README.md # This file ├── docs/ │ └── architecture.svg # System architecture diagram ├── .gitignore # Ignores .venv/ and result.json └── .venv/ # Virtual environment (not committed) ``` *作为个人学术项目构建,旨在展示如何通过注重成本效益的工具实现安全左移的容器安全。*
标签:DevSecOps, Web截图, 上游代理, 安全合规网关, 容器安全, 恶意代码分类, 自定义请求头, 请求拦截, 逆向工具