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
Productivité · SKILL.md

securing-container-registry-images

securing-container-registry-images

通过使用 Trivy 和 Grype 实施漏洞扫描、使用 Cosign 和 Sigstore 强制执行镜像签名、配置镜像仓库访问控制,以及构建阻止部署未扫描或未签名镜像的 CI/CD 流水线,来保护容器仓库(Container Registry)中的镜像安全。

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: securing-container-registry-images description: > 通过使用 Trivy 和 Grype 实施漏洞扫描、使用 Cosign 和 Sigstore 强制执行镜像签名、配置镜像仓库访问控制,以及构建阻止部署未扫描或未签名镜像的 CI/CD 流水线,来保护容器仓库(Container Registry)中的镜像安全。 domain: cybersecurity subdomain: cloud-security tags: [cloud-security, containers, registry, image-scanning, trivy, cosign, supply-chain] version: "1.0" author: mahipal license: Apache-2.0

保护容器仓库镜像

适用场景

  • 为容器镜像仓库(ECR、ACR、GCR、Docker Hub)建立安全管控时
  • 构建在镜像晋级前强制执行漏洞扫描的 CI/CD 流水线时
  • 实施镜像签名(Image Signing)和验证以防止供应链攻击时
  • 审计现有镜像仓库中存在漏洞、未扫描或未签名的镜像时
  • 合规要求为已部署容器镜像提供软件物料清单(SBOM,Software Bill of Materials)时

不适用于:运行时容器安全(使用 Falco 或 Sysdig)、Kubernetes 准入控制(在建立镜像仓库管控后使用 OPA Gatekeeper 或 Kyverno),或主机级漏洞扫描(使用 Amazon Inspector 或 Qualys)。

前置条件

  • 已安装 Trivy(brew install trivy 或 apt install trivy)
  • 已安装 Grype(curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh)
  • 已安装 Cosign(go install github.com/sigstore/cosign/v2/cmd/cosign@latest)
  • 已安装 Syft 用于生成 SBOM(curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh)
  • 具备容器镜像仓库访问权限(ECR、ACR、GCR 或私有仓库)

工作流程

步骤 1:使用 Trivy 扫描镜像漏洞

在推送到镜像仓库前后,对容器镜像运行全面的漏洞扫描。

# 扫描本地镜像漏洞
trivy image --severity HIGH,CRITICAL myapp:latest

# 扫描远程仓库中的镜像
trivy image --severity HIGH,CRITICAL 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

# 以 JSON 格式输出供 CI/CD 处理
trivy image --format json --output trivy-results.json myapp:latest

# 同时扫描漏洞和错误配置
trivy image --scanners vuln,misconfig,secret myapp:latest

# 扫描特定镜像并输出 SBOM
trivy image --format spdx-json --output sbom.json myapp:latest

# 发现严重漏洞时使 CI/CD 失败
trivy image --exit-code 1 --severity CRITICAL myapp:latest

步骤 2:使用 Grype 进行补充扫描

使用 Grype 作为互补扫描器,覆盖更广泛的漏洞数据库。

# 使用 Grype 扫描镜像
grype myapp:latest

# 设置严重级别阈值
grype myapp:latest --fail-on critical

# 以 JSON 格式输出供处理
grype myapp:latest -o json > grype-results.json

# 扫描 SBOM 而非直接扫描镜像
syft myapp:latest -o spdx-json > sbom.json
grype sbom:sbom.json

# 扫描基于目录的镜像导出
grype dir:/path/to/image-rootfs

步骤 3:生成软件物料清单(SBOM)

为所有镜像创建 SBOM,以维护软件组件和依赖项的完整清单。

# 使用 Syft 以 SPDX 格式生成 SBOM
syft myapp:latest -o spdx-json > sbom-spdx.json

# 以 CycloneDX 格式生成 SBOM
syft myapp:latest -o cyclonedx-json > sbom-cyclonedx.json

# 将 SBOM 作为 OCI artifact 附加到镜像
cosign attach sbom --sbom sbom-spdx.json \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

# 验证 SBOM 内容
syft myapp:latest -o table | head -50

步骤 4:使用 Cosign 和 Sigstore 签名镜像

实施镜像签名(Image Signing),确保供应链中镜像的完整性和真实性。

# 生成签名密钥对
cosign generate-key-pair

# 对仓库中的镜像进行签名
cosign sign --key cosign.key \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

# 使用 Sigstore 的无密钥签名(基于 OIDC)
cosign sign --yes \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

# 验证镜像签名
cosign verify --key cosign.pub \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

# 验证无密钥签名
cosign verify \
  --certificate-identity developer@company.com \
  --certificate-oidc-issuer https://accounts.google.com \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

# 附加包含扫描结果的证明(Attestation)
cosign attest --predicate trivy-results.json \
  --key cosign.key \
  123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

步骤 5:配置镜像仓库级别安全控制

为 ECR、ACR 和 GCR 设置各仓库特定的安全功能。

# AWS ECR:启用推送时自动扫描
aws ecr put-image-scanning-configuration \
  --repository-name myapp \
  --image-scanning-configuration scanOnPush=true

# ECR:设置镜像标签不可变性(防止覆盖标签)
aws ecr put-image-tag-mutability \
  --repository-name myapp \
  --image-tag-mutability IMMUTABLE

# ECR:设置生命周期策略以清理未标记的镜像
aws ecr put-lifecycle-policy \
  --repository-name myapp \
  --lifecycle-policy-text '{
    "rules": [{
      "rulePriority": 1,
      "description": "Remove untagged images after 7 days",
      "selection": {"tagStatus": "untagged", "countType": "sinceImagePushed", "countUnit": "days", "countNumber": 7},
      "action": {"type": "expire"}
    }]
  }'

# ECR:获取某镜像的扫描结果
aws ecr describe-image-scan-findings \
  --repository-name myapp \
  --image-id imageTag=latest \
  --query 'imageScanFindings.findingSeverityCounts'

# Azure ACR:启用容器仓库的 Defender for Cloud
az security pricing create --name ContainerRegistry --tier standard

# GCR:启用容器分析(Container Analysis)
gcloud services enable containeranalysis.googleapis.com
gcloud artifacts docker images list-vulnerabilities \
  LOCATION-docker.pkg.dev/PROJECT/REPO/IMAGE@sha256:DIGEST

步骤 6:构建带安全门禁的 CI/CD 流水线

将扫描和签名作为强制门禁集成到 CI/CD 流水线中。

# GitHub Actions:扫描、签名并推送镜像
name: Container Security Pipeline
on: push

jobs:
  build-scan-sign:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

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

      - name: Trivy vulnerability scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          format: json
          output: trivy-results.json
          severity: CRITICAL,HIGH
          exit-code: 1

      - name: Generate SBOM
        run: syft myapp:${{ github.sha }} -o spdx-json > sbom.json

      - name: Push to ECR
        run: |
          aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
          docker tag myapp:${{ github.sha }} $ECR_REGISTRY/myapp:${{ github.sha }}
          docker push $ECR_REGISTRY/myapp:${{ github.sha }}

      - name: Sign image with Cosign
        run: |
          cosign sign --key env://COSIGN_PRIVATE_KEY \
            $ECR_REGISTRY/myapp:${{ github.sha }}

      - name: Attach SBOM
        run: |
          cosign attach sbom --sbom sbom.json \
            $ECR_REGISTRY/myapp:${{ github.sha }}

核心概念

术语定义
容器镜像扫描(Container Image Scanning)对容器镜像各层进行自动化分析,识别操作系统包和应用程序依赖中的已知漏洞
镜像签名(Image Signing)使用 Cosign 或 Notation 对容器镜像真实性和完整性进行加密证明的验证机制
软件物料清单(SBOM)容器镜像中软件组件、库和依赖项的完整清单
标签不可变性(Tag Immutability)防止覆盖现有镜像标签的仓库设置,确保标签始终指向同一个镜像摘要
Sigstore为软件供应链安全提供无密钥签名、透明度日志和验证工具的开源项目
镜像证明(Image Attestation)附加到镜像的经加密签名的元数据(扫描结果、SBOM、构建来源),可在部署前进行验证

工具与系统

  • Trivy:面向容器镜像、文件系统、Git 仓库和 Kubernetes 资源的综合漏洞扫描工具
  • Grype:Anchore 出品的漏洞扫描工具,对容器镜像和 SBOM 具有广泛的漏洞数据库覆盖
  • Cosign:Sigstore 工具集,支持基于密钥和无密钥工作流的镜像签名、验证和证明
  • Syft:SBOM 生成工具,支持针对容器镜像和文件系统的 SPDX 和 CycloneDX 格式
  • AWS ECR:内置扫描、标签不可变性和生命周期策略的容器镜像仓库

常见场景

场景:实施安全的镜像晋级流水线

场景背景:开发团队在没有安全管控的情况下将镜像推送到开发仓库。安全团队需要实施一个晋级流水线,对镜像进行扫描、签名,并仅将经过审批的镜像晋级到生产仓库。

方法:

  1. 为开发仓库配置 ECR 推送时自动扫描
  2. 将 Trivy 扫描作为 CI/CD 门禁,阻止含严重(CRITICAL)漏洞的镜像
  3. 使用 Syft 生成 SBOM 并与镜像扫描结果一起存储
  4. 扫描通过后使用 Cosign 对已审批镜像进行签名
  5. 配置生产仓库,要求所有推送的镜像必须包含签名
  6. 在生产 Kubernetes 中配置 Kyverno 或 OPA Gatekeeper,在 Pod 创建前验证镜像签名
  7. 在两个仓库中实施生命周期策略,清理未标记和旧镜像

常见陷阱:漏洞数据库持续更新。今天通过扫描的镜像,明天可能发现新的严重漏洞。应对已部署的镜像实施持续扫描,而不仅限于构建时扫描。镜像签名密钥必须安全存储在 KMS 或 Vault 中,不能存放在 CI/CD 环境变量里。

输出格式

容器仓库安全报告
=====================================
仓库: 123456789012.dkr.ecr.us-east-1.amazonaws.com
镜像库数量: 24
报告日期: 2026-02-23

镜像清单:
  总镜像数: 342
  已扫描: 298 (87%)
  已签名: 156 (46%)
  含 SBOM: 134 (39%)

漏洞摘要:
  严重漏洞:    23 个(分布在 8 个镜像中)
  高危漏洞:   145 个(分布在 34 个镜像中)
  中危漏洞:   456 个(分布在 67 个镜像中)
  无漏洞镜像:  89 个

需立即修复的严重镜像:
  myapp:1.2.3           - 5 个严重漏洞(openssl 中的 CVE-2026-xxxx)
  api-gateway:2.0.1     - 3 个严重漏洞(log4j 中的 CVE-2026-yyyy)
  worker:latest         - 4 个严重漏洞(glibc 中的 CVE-2026-zzzz)

仓库配置状态:
  推送时扫描已启用:     18 / 24 个仓库
  标签不可变性:         12 / 24 个仓库
  生命周期策略:         20 / 24 个仓库
  强制镜像签名:          8 / 24 个仓库
Skills enregistrées