Die Oberfläche ist lokalisiert; Skill-Beschreibungen und -Dokumente werden per KI automatisch in Ihre Sprache übersetzt. Code, Befehle, Pfade und Fachbegriffe bleiben im Original, maßgeblich ist das Dokument des Autors.
Skills entdecken
Produktivität · 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

Skill-Dokumentation

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 个仓库
Gespeicherte Skills