容器镜像安全基础
容器镜像并非一个单一的文件,而是由多层只读文件系统叠加而成的联合文件系统。理解镜像的分层原理,是识别漏洞来源、评估安全水位的前提。本章从分层机制出发,系统梳理镜像中常见的漏洞类型与安全风险。
2.1 镜像分层原理
Docker 镜像采用 UnionFS(联合文件系统)技术,每一层对应 Dockerfile 中的一条指令。层与层之间通过 写时复制(Copy-on-Write, CoW) 机制实现共享与隔离。
核心概念: 基础层(Base Layer)通常为操作系统发行版(如 Ubuntu 22.04、Alpine 3.18),上层叠加应用依赖、配置文件、二进制文件。每一层只记录与上一层的差异(diff)。
分层结构带来的安全影响:
- 层共享:多个镜像共用同一基础层,基础层中的漏洞会扩散到所有派生镜像。
- 层缓存:CI/CD 中若使用缓存层,可能引入过时或已废弃的依赖。
- 层历史:每一层都保留历史文件,即使后续层删除了敏感文件,底层仍可被提取。
2.2 镜像漏洞来源
镜像中的漏洞主要来自三个维度:基础镜像、应用依赖、构建过程。以下表格按来源分类,并给出典型示例。
| 漏洞来源 | 典型场景 | 风险等级 | 示例 |
|---|---|---|---|
| 基础镜像过时 | 使用 Ubuntu 20.04 而非 22.04 LTS,内核/glibc 漏洞未修复 | 高 | CVE-2023-2640(Ubuntu OverlayFS 提权) |
| 应用依赖漏洞 | npm/pip/maven 引入已知 CVE 的库 | 中-高 | log4j2(CVE-2021-44228) |
| 构建时引入恶意软件 | 从不可信源下载二进制、使用被篡改的基础镜像 | 严重 | 挖矿木马、后门程序 |
| 配置泄露 | Dockerfile 中硬编码密钥、环境变量暴露 | 高 | 数据库密码、 |
| 层历史残留 | 中间层遗留 .git 目录、.env 文件、SSH 私钥 | 中 | git 历史中的敏感信息 |
巡检要点: 在容量规划场景中,基础镜像过时不仅带来安全风险,还会导致镜像体积膨胀(旧包未清理),间接影响拉取时间和节点磁盘水位。
2.3 常见镜像安全风险
以下三类风险在镜像安全水位巡检中最为高频,也是 Cosign 签名验证需要重点覆盖的场景。
2.3.1 恶意软件植入
攻击者通过篡改公共镜像仓库、中间人攻击或供应链污染,在镜像中植入挖矿程序、反弹 shell、勒索软件等。典型特征:
- 镜像体积异常增大(如 alpine 基础镜像从 5MB 变为 200MB)
- 存在未知的二进制文件(如 /tmp/.systemd、/usr/bin/networkd)
- 启动命令包含 curl/wget 下载外部 payload
2.3.2 敏感信息泄露
开发者在构建镜像时,常将密钥、证书、配置文件直接写入镜像层。即使后续层删除,底层仍可通过 docker history 或 skopeo inspect 提取。
# 危险示例:Dockerfile 中直接写入密钥
FROM python:3.11-slim
COPY . /app
RUN echo "export DB_PASSWORD=supersecret" >> /etc/profile # 泄露!
RUN rm -rf /app/.git # 删除后底层仍可恢复
容量规划关联: 敏感信息泄露本身不直接影响容量,但若密钥被用于横向移动,攻击者可能批量拉取镜像、创建大量容器,导致节点资源耗尽。
2.3.3 基础镜像过时
基础镜像长期不更新,累积大量已知 CVE。在容量规划视角下,过时基础镜像往往体积更大(包含已废弃的包),且无法享受新版本的安全优化和体积缩减。
| 基础镜像 | 版本 | 镜像大小 | 已知 CVE 数(2025-01) |
|---|---|---|---|
| Ubuntu | 20.04 | ~72 MB | 87 |
| Ubuntu | 22.04 | ~77 MB | 23 |
| Alpine | 3.16 | ~5.6 MB | 12 |
| Alpine | 3.19 | ~5.8 MB | 2 |
从上表可见,Ubuntu 20.04 比 22.04 的 CVE 数量高出近 4 倍,而 Alpine 3.16 到 3.19 的 CVE 数量从 12 降至 2。定期更新基础镜像是降低安全水位最直接的手段。
2.4 安全水位巡检清单
基于上述风险,在容量规划巡检中应至少检查以下项目:
- 基础镜像版本:是否使用最新 LTS 或 Alpine 稳定版?
- 层数控制:镜像层数是否超过 20 层?过多层数增加扫描负担和拉取时间。
- 敏感文件扫描:是否包含 .env、.pem、.key、.git 目录?
- 已知 CVE 数量:高危/严重 CVE 是否清零?
- 签名状态:镜像是否经过 Cosign 签名?签名是否有效?
- 镜像体积基线:是否超过团队设定的体积阈值(如 500MB)?
实践建议: 将以上巡检项集成到 CI/CD 流水线中,每次构建后自动生成安全水位报告。结合容量规划数据(镜像拉取耗时、节点磁盘使用率),动态调整基础镜像更新策略。