| 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
trivy image --format json --output trivy-results.json myapp:latest
trivy image --scanners vuln,misconfig,secret myapp:latest
trivy image --format spdx-json --output sbom.json myapp:latest
trivy image --exit-code 1 --severity CRITICAL myapp:latest
步骤 2:使用 Grype 进行补充扫描
使用 Grype 作为互补扫描器,覆盖更广泛的漏洞数据库。
grype myapp:latest
grype myapp:latest --fail-on critical
grype myapp:latest -o json > grype-results.json
syft myapp:latest -o spdx-json > sbom.json
grype sbom:sbom.json
grype dir:/path/to/image-rootfs
步骤 3:生成软件物料清单(SBOM)
为所有镜像创建 SBOM,以维护软件组件和依赖项的完整清单。
syft myapp:latest -o spdx-json > sbom-spdx.json
syft myapp:latest -o cyclonedx-json > sbom-cyclonedx.json
cosign attach sbom --sbom sbom-spdx.json \
123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
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
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
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 put-image-scanning-configuration \
--repository-name myapp \
--image-scanning-configuration scanOnPush=true
aws ecr put-image-tag-mutability \
--repository-name myapp \
--image-tag-mutability IMMUTABLE
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"}
}]
}'
aws ecr describe-image-scan-findings \
--repository-name myapp \
--image-id imageTag=latest \
--query 'imageScanFindings.findingSeverityCounts'
az security pricing create --name ContainerRegistry --tier standard
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 流水线中。
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 }}
核心概念
| 术语 | 定义 |
|---|
| 容器镜像扫描(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:内置扫描、标签不可变性和生命周期策略的容器镜像仓库
常见场景
场景:实施安全的镜像晋级流水线
场景背景:开发团队在没有安全管控的情况下将镜像推送到开发仓库。安全团队需要实施一个晋级流水线,对镜像进行扫描、签名,并仅将经过审批的镜像晋级到生产仓库。
方法:
- 为开发仓库配置 ECR 推送时自动扫描
- 将 Trivy 扫描作为 CI/CD 门禁,阻止含严重(CRITICAL)漏洞的镜像
- 使用 Syft 生成 SBOM 并与镜像扫描结果一起存储
- 扫描通过后使用 Cosign 对已审批镜像进行签名
- 配置生产仓库,要求所有推送的镜像必须包含签名
- 在生产 Kubernetes 中配置 Kyverno 或 OPA Gatekeeper,在 Pod 创建前验证镜像签名
- 在两个仓库中实施生命周期策略,清理未标记和旧镜像
常见陷阱:漏洞数据库持续更新。今天通过扫描的镜像,明天可能发现新的严重漏洞。应对已部署的镜像实施持续扫描,而不仅限于构建时扫描。镜像签名密钥必须安全存储在 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 个仓库