L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Déploiement et opérations · SKILL.md

scanning-containers-with-trivy-in-cicd

scanning-containers-with-trivy-in-cicd

本技能涵盖将 Aqua Security 的 Trivy 扫描器集成到 CI/CD 流水线中,用于全面的容器镜像漏洞检测。包括扫描 Docker 镜像中的操作系统包和应用依赖 CVE、检测 Dockerfile 中的错误配置、扫描文件系统和 Git 仓库,以及建立基于严重性的质量门禁以阻止有漏洞的镜像部署。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: scanning-containers-with-trivy-in-cicd description: > 本技能涵盖将 Aqua Security 的 Trivy 扫描器集成到 CI/CD 流水线中,用于全面的容器镜像漏洞检测。包括扫描 Docker 镜像中的操作系统包和应用依赖 CVE、检测 Dockerfile 中的错误配置、扫描文件系统和 Git 仓库,以及建立基于严重性的质量门禁以阻止有漏洞的镜像部署。 domain: cybersecurity subdomain: devsecops tags: [devsecops, cicd, trivy, container-security, vulnerability-scanning, secure-sdlc] version: 1.0.0 author: mahipal license: Apache-2.0

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

适用场景

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

不适用于:运行时容器安全监控(应使用 Falco)、扫描生产中正在运行的容器(应使用运行时代理)、或仅扫描未容器化的应用源代码(应使用 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: 构建 Docker 镜像
        run: docker build -t app:${{ github.sha }} .

      - name: 运行 Trivy 漏洞扫描器
        uses: aquasecurity/trivy-action@0.28.0
        with:
          image-ref: 'app:${{ github.sha }}'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
          ignore-unfixed: true

      - name: 上传 Trivy 扫描结果
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'
          category: 'trivy-container'

      - name: 运行 Trivy 错误配置扫描器
        uses: aquasecurity/trivy-action@0.28.0
        with:
          scan-type: 'config'
          scan-ref: '.'
          format: 'table'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'

步骤 2:扫描 Dockerfile 中的错误配置

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

# 扫描 Dockerfile 中的错误配置
trivy config --severity HIGH,CRITICAL ./Dockerfile

# 使用自定义策略目录扫描
trivy config --policy ./security-policies --severity MEDIUM,HIGH,CRITICAL .

# Trivy 检查的安全 Dockerfile 实践示例:
# - 存在 USER 指令(不以 root 运行)
# - 已定义 HEALTHCHECK 指令
# - 基础镜像使用特定标签,而非 :latest
# - ENV 或 ARG 指令中无密钥信息
# - 优先使用 COPY 而非 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 快速重置 - 已在负载均衡器层面缓解
    statement: "已通过入口层 WAF 速率限制缓解"
    expires: 2026-06-01

  - id: CVE-2024-21626    # runc 容器逃逸 - 基础镜像更新中已修补
    statement: "在 JIRA-SEC-1234 中跟踪,基础镜像更新已计划"
    expires: 2026-03-15

misconfigurations:
  - id: DS002             # 未设置 User - init 容器需要 root 权限
    paths:
      - "docker/init-container/Dockerfile"
    statement: "Init 容器需要 root 权限设置卷权限"

步骤 5:实现数据库缓存和离线扫描

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

# 带数据库缓存的 GitHub Actions
- name: 缓存 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: 使用缓存 DB 运行 Trivy
  uses: aquasecurity/trivy-action@0.28.0
  with:
    image-ref: 'app:${{ github.sha }}'
    cache-dir: /tmp/trivy-db
    format: 'json'
    output: 'trivy-results.json'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'
# 隔离网络:手动下载 DB 并挂载
trivy image --download-db-only --cache-dir /path/to/cache
# 将缓存传输到隔离网络系统
trivy image --skip-db-update --cache-dir /path/to/cache myimage:tag

步骤 6:生成 SBOM 并扫描许可证合规性

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

# 以 CycloneDX 格式生成 SBOM
trivy image --format cyclonedx --output sbom.cdx.json app:latest

# 以 SPDX 格式生成 SBOM
trivy image --format spdx-json --output sbom.spdx.json app:latest

# 扫描 SBOM 中的漏洞(将生成与扫描解耦)
trivy sbom sbom.cdx.json --severity CRITICAL,HIGH

# 带许可证检测的扫描
trivy image --scanners vuln,license --severity HIGH,CRITICAL app:latest

关键概念

术语定义
CVE通用漏洞与披露 — 公开已知安全漏洞的标准化标识符
漏洞数据库Trivy 定期更新的数据库,汇聚来自 NVD、厂商公告和语言特定来源的 CVE 数据
错误配置Dockerfile、Kubernetes 清单或 IaC 模板中与安全相关的配置问题
SBOM软件物料清单 — 容器镜像中所有组件和依赖项的完整清单
忽略未修复跳过没有可用补丁的 CVE 的标志,减少无法采取行动漏洞带来的噪音
VEX漏洞可利用性交换 — 关于漏洞在特定上下文中是否可被利用的机器可读声明
退出码Trivy 在发现超过严重性阈值时返回的非零状态码,用于使 CI/CD 流水线失败

工具与系统

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

常见场景

场景:多阶段构建,分离扫描与推送

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

方法:

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

注意事项:仅扫描最终阶段会遗漏构建阶段中存在的易受攻击包,这些包可能影响了构建过程。需单独对构建上下文运行 trivy fs。过度缓存 Trivy DB(每周一次)意味着新发布的 CVE 需要数天才能出现在扫描中。

输出格式

Trivy 容器扫描报告
=============================
镜像: app:a1b2c3d4
基础镜像: python:3.12-slim-bookworm
扫描日期: 2026-02-23
DB 版本: 2026-02-23T00:15:00Z

漏洞摘要:
  总计: 47
  严重: 2
  高危: 5
  中危: 18
  低危: 22
  未修复: 8 (已从门禁中排除)

严重发现:
  CVE-2025-12345  libssl3    3.0.11-1  3.0.13-1  OpenSSL 缓冲区溢出
  CVE-2025-67890  curl       7.88.1-10 7.88.1-12 curl HSTS 绕过

高危发现:
  CVE-2025-11111  zlib1g     1.2.13    1.2.13.1  zlib 堆缓冲区溢出
  CVE-2025-22222  python3.12 3.12.1    3.12.3    CPython 路径穿越
  CVE-2025-33333  requests   2.31.0    2.32.0    requests 重定向中的 SSRF

错误配置:
  DS002  [HIGH]   Dockerfile: 未设置 USER 指令(以 root 运行)
  DS026  [MEDIUM] Dockerfile: 未定义 HEALTHCHECK

质量门禁: 失败(2 个严重,5 个高危发现)
Skills enregistrées