供应链攻击防御
什么是容器供应链攻击
容器供应链攻击是指攻击者通过污染容器镜像的构建过程,将恶意代码注入到最终交付的镜像中。这些攻击可以发生在镜像生命周期的任何一个环节:从基础镜像选择、依赖下载、构建过程到镜像分发。
供应链攻击的类型
1. 基础镜像污染
# 攻击者可能在 Docker Hub 上发布
# 带有后门的 "官方" 镜像
docker pull nginx:latest # 真的是官方的吗?
docker pull node:18 # 是否已被篡改?
常见攻击手段:
– 仿冒官方仓库(如 nginix vs nginx)
– 篡改官方镜像的某一层
– 在镜像中植入挖矿程序或后门
2. 依赖投毒
FROM node:18-alpine
# 攻击者可能向流行的 npm 包注入恶意代码
RUN npm install left-pad # 该包可能被上游篡改
# 或 CDN 上的文件被替换
RUN curl -O https://cdn.example.com/tool.sh && bash tool.sh
3. 构建过程劫持
- 篡改 CI/CD 配置
- 污染容器镜像仓库
- 中间人攻击替换下载的文件
历史安全事件
| 事件 | 年份 | 影响 |
|---|---|---|
| Codecov 供应链攻击 | 2021 | 从 CI 中窃取凭据 |
| SolarWinds 攻击 | 2020 | 植入后门的更新包 |
| npm event-stream | 2018 | 包含加密货币窃取器 |
| Docker Hub 数据泄露 | 2019 | 19 万用户信息泄露 |
防御策略
1. 使用可信基础镜像
# 使用官方镜像(经过验证)
docker pull nginx:1.24-alpine
# 使用固定摘要(不可变引用)
docker pull nginx@sha256:abc123def456...
# 使用 Docker Official Images 标识
# Docker Hub 上有 "Official Image" 标签
2. 使用镜像摘要(Digest)
services:
web:
# 使用摘要而不是标签
image: nginx@sha256:abc123def456789...
# 获取镜像摘要
docker pull nginx:alpine
docker images --digests nginx
# 推送时获取
docker push myrepo/myapp:latest
# The push refers to repository [myrepo/myapp]
# latest: digest: sha256:abc123... size: 1234
3. 镜像签名验证
# Docker Content Trust
export DOCKER_CONTENT_TRUST=1
docker pull myrepo/myapp:latest
# 验证失败时拒绝拉取
# Cosign 验证
cosign verify --key cosign.pub myrepo/myapp:latest
4. SBOM(软件物料清单)
# 生成 SBOM
docker sbom nginx:alpine
# Syft 工具
syft nginx:alpine -o table
# 输出示例
NAME VERSION TYPE
alpine-base 3.18.0 apk
libcrypto3 3.1.0 apk
libssl3 3.1.0 apk
5. 构建时验证
# 验证下载文件的完整性
FROM alpine:3.18
# 使用 checksum 验证下载
RUN curl -O https://example.com/tool.tar.gz && \
echo "sha256:abc123... tool.tar.gz" | sha256sum -c && \
tar xzf tool.tar.gz
# 使用 GPG 签名验证
RUN curl -O https://example.com/tool.tar.gz && \
curl -O https://example.com/tool.tar.gz.asc && \
gpg --verify tool.tar.gz.asc tool.tar.gz
6. 最小基础镜像
# 使用 Distroless 或 Scratch
# 减少攻击面
FROM gcr.io/distroless/base-debian11
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]
CI/CD 中的供应链安全
# GitHub Actions 供应链安全示例
name: Build and Verify
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# 验证依赖完整性
- name: Verify dependencies
run: |
sha512sum -c checksums.txt
# 构建镜像
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
# 漏洞扫描
- name: Scan for vulnerabilities
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
# 生成 SBOM
- name: Generate SBOM
uses: anchore/sbom-action@v0
# 签名镜像
- name: Sign image
run: cosign sign --key cosign.key myapp:${{ github.sha }}
# 推送
- name: Push
run: docker push myapp:${{ github.sha }}
防御多层模型
供应链攻击防御层次:
第 1 层:基础镜像选择(官方、最小化)
第 2 层:依赖管理(锁定版本、验证完整性)
第 3 层:构建过程(可重复构建、审查)
第 4 层:镜像存储(签名、访问控制)
第 5 层:部署验证(准入控制)
第 6 层:运行时监控(检测异常行为)
镜像拉取策略
# 在 Kubernetes 中使用拉取策略
spec:
containers:
- name: app
image: myrepo/myapp@sha256:abc123...
imagePullPolicy: IfNotPresent
# Always: 每次拉取
# IfNotPresent: 仅当本地不存在时
# Never: 仅使用本地镜像
最佳实践
- 固定镜像摘要:使用
@sha256:而不是标签 - 启用内容信任:打开
DOCKER_CONTENT_TRUST - 定期扫描镜像:在 CI 中集成 Trivy
- 生成和审查 SBOM:了解镜像中的所有组件
- 最小化基础镜像:减少攻击面
- 签名所有镜像:确保镜像的完整性和来源可追溯
- 锁定依赖版本:使用 lock 文件
- 审计所有外部源:不要执行未经审查的脚本
供应链攻击无法完全消除,但通过多层次防御可以将风险降到最低。每个环节的验证和检查都是抵御供应链攻击的关键防线。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END


暂无评论内容