mcpField
S
scanning-containers-with-trivy-in-cicd

scanning-containers-with-trivy-in-cicd

github.com/mukul975安全35.2k127 次安装8 周前更新
代码仓库

关于 scanning-containers-with-trivy-in-cicd

这是在 CI/CD 中使用 Trivy 扫描容器与配置的工作流技能,面向构建和安全团队。它介绍如何在镜像推送前检查漏洞与错误配置,并生成 SBOM、管理例外及缓存漏洞数据库。

主要功能

  1. 01扫描容器镜像中的漏洞
  2. 02检查 Dockerfile 和基础设施配置
  3. 03按严重级别设置流水线门槛
  4. 04配置忽略项与 VEX 例外
  5. 05生成 SBOM 并缓存漏洞数据库

适用场景

  1. 01在镜像推送前阻止高危漏洞
  2. 02在 CI/CD 中检查 Dockerfile 配置
  3. 03为镜像生成 CycloneDX 或 SPDX SBOM
  4. 04在离线环境复用漏洞数据库

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill scanning-containers-with-trivy-in-cicd

安装后在 Claude Code 中输入/scanning-containers-with-trivy-in-cicd确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
assets/
template.md
references/
api-reference.md
standards.md
workflows.md
scripts/
agent.py
process.py

详细介绍

在 CI/CD 中使用 Trivy 扫描容器

何时使用

  • 在 CI/CD 中构建 Docker 容器镜像,并需要在推送到镜像仓库前进行自动化漏洞扫描时
  • 在建立质量门禁,防止包含严重或高危 CVE 的镜像进入生产环境时
  • 当合规要求强制规定所有容器镜像在部署前必须进行漏洞扫描时
  • 在扫描 IaC 文件(Dockerfile、Kubernetes 清单)的同时扫描容器镜像时
  • 在需要单一工具扫描操作系统软件包、特定语言依赖项和错误配置时

不要使用于运行时容器安全监控(请使用 Falco)、扫描生产环境中正在运行的容器(请使用运行时 Agent),或仅扫描未容器化的应用程序源代码(请使用 SAST 工具)。

前置条件

  • 已安装 Trivy CLI(v0.50+)或可访问 aquasecurity/trivy-action GitHub Action
  • CI/CD 中可使用 Docker 守护进程以构建和扫描镜像
  • 具有容器镜像仓库凭据,用于拉取基础镜像和推送已扫描的镜像
  • 可访问 Trivy 漏洞数据库(自动下载或已缓存)

工作流

步骤 1:在 GitHub Actions 中配置 Trivy 扫描

设置一个 GitHub Actions 工作流,构建 Docker 镜像并在推送到容器镜像仓库前使用 Trivy 进行扫描。

# .github/workflows/container-security.yml
name: Container Security Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
    paths:
      - 'Dockerfile'
      - 'docker-compose*.yml'
      - 'src/**'
      - 'requirements*.txt'
      - 'package*.json'

jobs:
  build-and-scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Build Docker image
        run: docker build -t app:${{ github.sha }} .

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/[email protected]
        with:
          image-ref: 'app:${{ github.sha }}'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
          ignore-unfixed: true

      - name: Upload Trivy scan results
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'
          category: 'trivy-container'

      - name: Run Trivy misconfiguration scanner
        uses: aquasecurity/[email protected]
        with:
          scan-type: 'config'
          scan-ref: '.'
          format: 'table'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'
步骤 2:扫描 Dockerfile 中的错误配置

Trivy 可检测常见的 Dockerfile 安全问题,例如以 root 身份运行、使用 latest 标签以及暴露不必要的端口。

# Scan Dockerfile for misconfigurations
trivy config --severity HIGH,CRITICAL ./Dockerfile

# Scan with custom policy directory
trivy config --policy ./security-policies --severity MEDIUM,HIGH,CRITICAL .

# Example secure Dockerfile practices Trivy checks for:
# - USER instruction present (not running as root)
# - HEALTHCHECK instruction defined
# - Base image uses specific tag, not :latest
# - No secrets in ENV or ARG instructions
# - COPY preferred over ADD
步骤 3:与 GitLab CI/CD 集成
# .gitlab-ci.yml
stages:
  - build
  - scan
  - push

variables:
  TRIVY_CACHE_DIR: .trivycache/

build:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker save $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -o image.tar
  artifacts:
    paths:
      - image.tar

trivy-scan:
  stage: scan
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  cache:
    paths:
      - .trivycache/
  script:
    - trivy image
        --input image.tar
        --exit-code 1
        --severity CRITICAL,HIGH
        --ignore-unfixed
        --format json
        --output trivy-report.json
    - trivy image
        --input image.tar
        --severity CRITICAL,HIGH,MEDIUM
        --format table
  artifacts:
    reports:
      container_scanning: trivy-report.json
    paths:
      - trivy-report.json
  allow_failure: false

push:
  stage: push
  needs: [trivy-scan]
  script:
    - docker load -i image.tar
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
步骤 4:配置 Trivy 忽略与例外处理

通过 Trivy 的忽略文件和 VEX 声明管理误报和已接受的风险。

# .trivyignore.yaml
vulnerabilities:
  - id: CVE-2023-44487    # HTTP/2 rapid reset - mitigated at load balancer
    statement: "Mitigated by WAF rate limiting at ingress layer"
    expires: 2026-06-01

  - id: CVE-2024-21626    # runc container escape - patched in base image update
    statement: "Tracked in JIRA-SEC-1234, base image update scheduled"
    expires: 2026-03-15

misconfigurations:
  - id: DS002             # User not set - required for init containers
    paths:
      - "docker/init-container/Dockerfile"
    statement: "Init container requires root for volume permission setup"
步骤 5:实现数据库缓存与离线扫描

在 CI/CD 中缓存 Trivy 漏洞数据库,以减少扫描时间并支持气隙环境。

# GitHub Actions with database caching
- name: Cache Trivy DB
  uses: actions/cache@v4
  with:
    path: /tmp/trivy-db
    key: trivy-db-${{ hashFiles('.github/workflows/container-security.yml') }}
    restore-keys: trivy-db-

- name: Run Trivy with cached DB
  uses: aquasecurity/[email protected]
  with:
    image-ref: 'app:${{ github.sha }}'
    cache-dir: /tmp/trivy-db
    format: 'json'
    output: 'trivy-results.json'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'
# Air-gapped: Download DB manually and mount
trivy image --download-db-only --cache-dir /path/to/cache
# Transfer cache to air-gapped system
trivy image --skip-db-update --cache-dir /path/to/cache myimage:tag
步骤 6:生成 SBOM 并扫描许可证合规性

使用 Trivy 在漏洞扫描的同时生成软件物料清单。

# Generate SBOM in CycloneDX format
trivy image --format cyclonedx --output sbom.cdx.json app:latest

# Generate SBOM in SPDX format
trivy image --format spdx-json --output sbom.spdx.json app:latest

# Scan SBOM for vulnerabilities (decouple generation from scanning)
trivy sbom sbom.cdx.json --severity CRITICAL,HIGH

# Scan with license detection
trivy image --scanners vuln,license --severity HIGH,CRITICAL app:latest

关键概念

术语定义
CVECommon Vulnerabilities and Exposures — 针对公开已知安全漏洞的标准化标识符
漏洞数据库Trivy 定期更新的数据库,汇总来自 NVD、厂商公告和特定语言来源的 CVE 数据
错误配置Dockerfile、Kubernetes 清单或 IaC 模板中与安全相关的配置问题
SBOMSoftware Bill of Materials — 容器镜像中所有组件和依赖项的完整清单
忽略未修复项跳过没有可用补丁的 CVE 的标志,减少没有可行修复方案的漏洞带来的噪音
VEXVulnerability Exploitability eXchange — 关于漏洞在特定上下文中是否可被利用的机器可读声明
退出码当发现的问题超过严重性阈值时 Trivy 返回的非零代码,用于使 CI/CD 流水线失败

工具与系统

  • Trivy:Aqua Security 推出的开源漏洞扫描器,支持镜像、文件系统、仓库和 IaC
  • trivy-action:用于在 GitHub Actions 工作流中运行 Trivy 扫描的官方 GitHub Action
  • Trivy Operator:使用 Trivy 持续扫描集群工作负载的 Kubernetes Operator
  • Grype:Anchore 推出的替代镜像扫描器,用于对比和验证扫描结果
  • Harbor:内置 Trivy 集成的容器镜像仓库,可在推送时自动扫描镜像

常见场景

场景:分阶段构建与独立的扫描和推送

背景:团队构建多阶段 Docker 镜像,需要在推送到 ECR 之前扫描最终生产镜像,同时还要扫描构建阶段以发现供应链风险。

方法:

  1. 使用 --target production 构建最终阶段的 Docker 镜像
  2. 运行 Trivy,使用 --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed 阻止可被利用的问题
  3. 生成 CycloneDX 格式的 SBOM 并作为构建产物存储
  4. 将 SARIF 结果上传到 GitHub Security 标签页以便查看
  5. 仅当 Trivy 扫描退出代码为 0 时,才推送到 ECR
  6. 为推送的镜像打上扫描时间戳和 Trivy DB 版本标签,以便审计追溯

陷阱:仅扫描最终阶段会遗漏构建阶段中存在的、可能已影响构建的易受攻击包。请单独对构建上下文运行 trivy fs。过于激进地缓存 Trivy DB(每周一次)意味着新发布的 CVE 需要数天才会出现在扫描中。

输出格式

Trivy Container Scan Report
=============================
Image: app:a1b2c3d4
Base Image: python:3.12-slim-bookworm
Scan Date: 2026-02-23
DB Version: 2026-02-23T00:15:00Z

VULNERABILITY SUMMARY:
  Total: 47
  Critical: 2
  High: 5
  Medium: 18
  Low: 22
  Unfixed: 8 (excluded from gate)

CRITICAL FINDINGS:
  CVE-2025-12345  libssl3    3.0.11-1  3.0.13-1  OpenSSL buffer overflow
  CVE-2025-67890  curl       7.88.1-10 7.88.1-12 curl HSTS bypass

HIGH FINDINGS:
  CVE-2025-11111  zlib1g     1.2.13    1.2.13.1  zlib heap buffer overflow
  CVE-2025-22222  python3.12 3.12.1    3.12.3    CPython path traversal
  CVE-2025-33333  requests   2.31.0    2.32.0    requests SSRF in redirects

MISCONFIGURATION:
  DS002  [HIGH]   Dockerfile: USER instruction not set (running as root)
  DS026  [MEDIUM] Dockerfile: No HEALTHCHECK defined

QUALITY GATE: FAILED (2 Critical, 5 High findings)

评论

支持 Markdown