强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Dockerfile 写作精讲 / 12 - 镜像安全

12 - 镜像安全:漏洞扫描、签名与 SBOM

12.1 安全威胁概览

容器镜像面临的主要安全威胁:

威胁类型说明示例
已知漏洞基础镜像或依赖中的 CVELog4Shell (CVE-2021-44228)
恶意软件镜像中包含挖矿程序等供应链攻击
配置错误以 root 运行、暴露端口等CIS Benchmark 违规
供应链攻击镜像被篡改镜像投毒
敏感信息泄露密钥、密码硬编码在镜像中.env 文件被复制到镜像

12.2 漏洞扫描:Trivy

安装 Trivy

# Ubuntu/Debian
sudo apt-get install trivy

# macOS
brew install trivy

# Docker 方式运行
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
    aquasec/trivy image myapp:latest

基本扫描

# 扫描镜像
trivy image myapp:latest

# 扫描本地 Dockerfile
trivy config Dockerfile

# 扫描目录(包含 Dockerfile、Kubernetes manifests 等)
trivy fs .

# 输出 JSON 格式
trivy image --format json --output result.json myapp:latest

# 仅显示高危和严重漏洞
trivy image --severity HIGH,CRITICAL myapp:latest

# 退出码(CI 集成)
trivy image --exit-code 1 --severity CRITICAL myapp:latest

扫描结果解读

myapp:latest (debian 12.4)
Total: 15 (UNKNOWN: 0, LOW: 5, MEDIUM: 6, HIGH: 3, CRITICAL: 1)

┌──────────────┬────────────────┬──────────┬─────────────────────────────────┐
│   Library    │ Vulnerability  │ Severity │         Fixed Version           │
├──────────────┼────────────────┼──────────┼─────────────────────────────────┤
│ libssl3      │ CVE-2024-0727  │ CRITICAL │ 3.0.13-1~deb12u1               │
│ curl         │ CVE-2024-2096  │ HIGH     │ 7.88.1-10+deb12u5              │
│ libcurl4     │ CVE-2024-2096  │ HIGH     │ 7.88.1-10+deb12u5              │
└──────────────┴────────────────┴──────────┴─────────────────────────────────┘

在 CI 中集成 Trivy

# GitHub Actions
name: Security Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .
      
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
      
      - name: Upload Trivy scan results to GitHub Security
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'

Trivy 忽略文件

# .trivyignore
# 忽略特定 CVE(需要评估风险后才可忽略)
CVE-2024-0727
# 忽略特定漏洞(带有效期)
CVE-2024-2096
  expires: 2026-12-31

12.3 其他扫描工具

工具特点安装方式
Trivy全面、快速、免费apt/brew/docker
GrypeAnchore 出品,速度快curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh
Docker ScoutDocker 官方集成docker scout cves myapp:latest
Snyk商业工具,有免费额度npm install -g snyk
ClairRed Hat 出品,可自建部署为服务

Docker Scout

# Docker Desktop 内置 Scout
docker scout cves myapp:latest

# 快速查看建议
docker scout recommendations myapp:latest

# 比较两个版本的漏洞
docker scout compare myapp:v1 myapp:v2

12.4 镜像签名:Cosign

Cosign 是 Sigstore 项目的一部分,用于对容器镜像进行签名和验证。

安装 Cosign

# 下载最新版
COSIGN_VERSION="v2.2.3"
curl -fsSL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64" \
    -o /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign

签名镜像

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

# 使用私钥签名
cosign sign --key cosign.key registry.example.com/myapp:latest

# 使用密钥签名并附加签名
cosign sign --key cosign.key \
    -a "commit=$(git rev-parse HEAD)" \
    -a "builder=$(whoami)" \
    registry.example.com/myapp:latest

验证签名

# 使用公钥验证
cosign verify --key cosign.pub registry.example.com/myapp:latest

# 输出验证结果
# The following checks were performed:
#   - The cosign claims were validated
#   - The signatures were verified against the specified public key

# 在 K8s 中强制验证(使用 Kyverno 或 OPA Gatekeeper)

Keyless 签名(无密钥)

# 使用 OIDC 身份签名(适合 CI/CD)
# 不需要管理密钥对
cosign sign \
    --yes \
    --identity-token=$(get-oidc-token) \
    registry.example.com/myapp:latest

# 在 GitHub Actions 中使用
# 直接使用 GITHUB_TOKEN,无需配置密钥

CI/CD 集成签名

# GitHub Actions 中签名
name: Build and Sign
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write  # OIDC
      contents: read
    steps:
      - uses: actions/checkout@v4
      
      - uses: docker/setup-buildx-action@v3
      
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
      
      - uses: sigstore/cosign-installer@v3
      
      - name: Sign image
        run: cosign sign --yes ghcr.io/${{ github.repository }}:${{ github.sha }}

12.5 SBOM(软件物料清单)

SBOM 记录了镜像中包含的所有软件组件及其版本,是供应链安全的基础。

生成 SBOM

# 使用 syft(Anchore 出品)
syft myapp:latest -o spdx-json > sbom.spdx.json
syft myapp:latest -o cyclonedx-json > sbom.cdx.json

# 使用 Docker SBOM 插件
docker sbom myapp:latest

# 附加 SBOM 到镜像(OCI artifact)
cosign attest --predicate sbom.spdx.json --type spdx \
    --key cosign.key \
    registry.example.com/myapp:latest

SBOM 内容示例

{
  "spdxVersion": "SPDX-2.3",
  "name": "myapp",
  "packages": [
    {
      "name": "openssl",
      "versionInfo": "3.0.13",
      "licenseConcluded": "Apache-2.0"
    },
    {
      "name": "curl",
      "versionInfo": "7.88.1",
      "licenseConcluded": "MIT"
    }
  ]
}

合规要求

标准/法规要求
美国行政令 14028联邦采购需提供 SBOM
EU CRA数字产品需提供 SBOM
PCI DSS 4.0软件清单与漏洞管理
ISO 27001资产管理与风险评估

12.6 安全基础镜像选择

最小化原则

# ❌ 包含大量不必要的工具
FROM ubuntu:22.04

# ✅ 使用精简镜像
FROM python:3.12-slim

# ✅ 使用 Distroless(无 shell、无包管理器)
FROM gcr.io/distroless/python3

# ✅ 使用 Chainguard Images(零 CVE 目标)
FROM cgr.dev/chainguard/python:latest

安全扫描策略

开发阶段:   trivy image --severity CRITICAL (仅阻断严重漏洞)
CI 阶段:    trivy image --severity HIGH,CRITICAL (阻断高危和严重)
生产阶段:   trivy image --exit-code 1 (阻断所有已知漏洞)

12.7 镜像安全检查清单

检查项方法
使用非 root 用户USER 指令
不安装不必要的包精简基础镜像
定期更新基础镜像Dependabot / Renovate
扫描漏洞Trivy / Grype
不硬编码秘密BuildKit secrets
签名镜像Cosign
生成 SBOMsyft / docker sbom
固定镜像版本使用 digest 或具体版本标签
设置只读文件系统docker run --read-only
限制资源--memory / --cpus

12.8 常见错误与排查

错误原因解决方案
扫描发现大量 CVE基础镜像过旧更新基础镜像版本
签名验证失败公钥不匹配或镜像被篡改检查密钥对和镜像来源
SBOM 不完整未包含所有依赖使用多阶段构建时在最终阶段生成
忽略的 CVE 重新出现.trivyignore 过期更新忽略文件

12.9 扩展阅读


上一章11 - BuildKit 高级特性 下一章13 - 语言最佳实践 — Node.js / Go / Java / Python / Rust 的专项模板。