跳转至

容器安全 — 供应链、镜像信任、加固与运行时防线

这一章的全景: 一个漏洞或一次错误配置,就能让整个环境失守——所以安全不是 某个工具,是全生命周期的防线。书里把它分成四层,本章按四层讲: 供应链(镜像从哪来、有没有被动过)→ 加固(容器里能做什么被限制到最小)→ secrets(密钥怎么进场)→ 运行时(跑起来之后谁盯着)。 每一层都给了"收益 vs 代价"的对照,这是本章最诚实的地方。

1. 供应链安全:镜像的来路

攻击面从构建之前就开始了。供应链层的三件套1:

  1. 用可信的基础镜像——官方镜像、验证过的发布者;
  2. 扫描——Trivy、Clair、Docker Scout 对照 CVE 库查已知漏洞(装 Trivy 可直接 用各平台包管理器或官方二进制;cosign 同理)2;
  3. 签名与验证——cosign 生成密钥对(cosign generate-key-pair)、 给推上注册表的镜像签名;签名要先于验证,镜像要先推后签,且别用 latest 这种 浮动标签3。

三层要叠成纵深防御(defense in depth):管道里要求验证签名;部署时 (Kubernetes 准入控制器、Connaisseur、Gatekeeper 策略)只放行签过名的镜像; 注册表层(Harbor + Cosign)可以要求"没签名不准拉"。哪怕一个漏洞漏网, 未签名或被篡改的镜像也进不了生产4。

2. 加固:把容器收紧到最小权限

加固(hardening)的定义:收紧设备、文件系统、权限与运行时约束,缩小攻击面、 降低出事时的损害5。书里给的清单,逐条接住:

非 root + 裁剪 capability。 很多官方镜像默认容器内 root——进程一旦逃逸或被攻破, root 权限给了它太多杠杆。Dockerfile 里 groupadd -r/useradd -r 建系统用户、 改文件属主、USER appuser 收尾;运行时再 --cap-drop ALL 先清空、 --cap-add 只加真正需要的(比如 NET_BIND_SERVICE 绑低端口)6。 --no-new-privileges 封死提权:就算进程想通过 setuid 或内核漏洞拿新权限也拿不到 (macOS 上用 --security-opt no-new-privilege:true 变体)6。

只读文件系统与最小挂载。 --read-only 把整个根文件系统变只读, 写操作只剩显式挂出来的目录(日志、tmp、上传各挂一个空卷)。 镜像侧:slim/Alpine 基底、distroless(无 shell 无包管理器)、多阶段构建把编译器 和构建缓存永远挡在最终镜像外7。

内核级安全机制。 会用才算会用容器: seccomp 过滤系统调用(Docker 默认带一个限制危险调用的 profile,可自定义 default.json);AppArmor/SELinux 给容器配安全策略,限制文件系统与资源访问; user namespace 把容器内 UID 重映射为宿主机非 root UID,逃逸了也拿不到什么; 还有几条铁律:非必要绝不 --privileged;--icc=false 禁止容器间默认互访8。

资源限额。 --memory、--cpus、--pids-limit、--ulimit: 防资源耗尽型 DoS(第 08 章的 cgroup 驾驶舱在这里是安全工具)9。

可检测、可替换。 Dockerfile 里加 HEALTHCHECK(--interval=30s --timeout=5s --start-period=5s --retries=3),让编排器能把不健康容器标出来重启; 被攻破或生病的容器直接换掉,不打补丁——不可变基础设施的心态10。

组合示例(hardened baseline):

  $ docker run --rm -p 4567:4567 \
        --read-only \
        --cap-drop ALL --cap-add NET_BIND_SERVICE \
        --no-new-privileges \
        --memory 256m --cpus 0.5 \
        hello-ruby:latest
  → 只读根fs、最小 capability、禁提权、CPU/内存限额、非 root——"a strong
    baseline you can build on"(书中原话)[^11]

代价表(本章最有价值的一张表)。 加固每加一条,都可能碰灵活性、性能或开发便利: capability 裁狠了,绑低端口这类正常操作也会失败;只读文件系统会让"顺手写个临时文件" 的程序报错;distroless 没有 shell,调试变难。做法是先精确盘点应用真正需要什么, 再按环境选平衡点——安全收益和代价要一起看,不是越多越好12。

3. Secrets:密钥怎么进场

红线(第 04、08 章已埋伏笔,这里收拢):密码、API key 绝不硬编码、绝不进镜像、 尽量不进环境变量(环境变量对任何能 inspect 容器的人可见)。 正确姿势:运行期从加密存储取(云厂的 Secrets Manager / Vault),或(书里演示的 Docker 做法)用 secrets 机制挂载——secret 被装进 /run/secrets/ 下的文件, 应用从文件读(DB_PASSWORD_FILE 指向路径),compose 里声明,容器外的人看不见明文13。

4. 运行时安全:Falco 们看住"不该发生的事"

静态防线都就位后,最后一层是行为监控:Falco(以及 Sysdig)监听容器内 的系统调用,规则命中就告警——典型规则:web 容器里突然起了个 shell、 进程读写它不该碰的路径、出现意料外的网络连接。这类"运行时检出"补的是 静态扫描的盲区:配置全对,也挡不住有人利用合法配置干坏事14。 (第 12 章的安全监控一节预告过它;在 Kubernetes 里它通常以 DaemonSet 形式 看住每个节点。)

5. 作者的判断与证据

  • "扫描 + 签名 + 执行"三层纵深是本章的核心架构判断, 一句原文值得记住:"even if a vulnerability slips through, an unsigned or tampered image cannot enter production"4。
  • 加固清单全部有实操命令(非 root、cap-drop、--read-only、--no-new-privileges、 seccomp、资源限额),且给了组合基线611——证据强度高于一般"最佳实践"罗列。
  • 代价表是诚实的:每条加固都列出 Potential Downsides 与 Mitigation, 没有假装安全免费12。
  • 工具名单(Trivy、cosign、Connaisseur、Gatekeeper、Falco)是 2026 年主流, 会随生态漂移。

判断(我们的,不是书里的): 本章四层防线对应一句话:"默认不信,处处留证"—— 镜像不信(扫描+签名)、进程不信(最小权限+只读)、配置不信(secrets 加密)、 行为不信(运行时监控)。这四层与 12 章的可观测性叠起来,才构成完整闭环: 防线挡不住的,至少要看得见。 如果错,会错在: 对资源充足的大厂,四层全建是常态;但对小团队, 四层全建的成本可能超过业务风险——本书没给"按威胁建模裁剪"的决策框架, 这是读者要自己补的一课。

6. 边界与局限

  • 签名/准入的配置依赖 Kubernetes(Connaisseur、Gatekeeper)——单机 Docker 场景里"执行"层要靠注册表(Harbor)或脚本补齐,书里以 K8s 为主语。
  • seccomp/AppArmor/SELinux 只给了入口,各写一套可用策略是专门的学问; 盲目套 default profile 也可能让正常应用报错。
  • Falco 一节偏概念,规则编写、告警路由、误报治理未展开。
  • macOS 上 --no-new-privileges 的替代写法这类平台细节散在各处。

7. 可带走的

  1. 供应链三件套:可信镜像 + 扫描(Trivy/Scout)+ 签名(cosign), 扫描/签名/执行三层纵深14。
  2. 签名先于验证、先推后签、不用浮动标签3。
  3. 加固清单:非 root、cap-drop ALL + 按需 cap-add、--no-new-privileges、 --read-only + 最小写挂载、slim/distroless/多阶段、seccomp/AppArmor/SELinux/ user namespace、资源限额、HEALTHCHECK678910。
  4. 组合基线命令照抄可用(--read-only --cap-drop ALL --no-new-privileges --memory --cpus)11。
  5. 加固有代价:按应用真实需求盘点,再选平衡点12。
  6. secrets 走 /run/secrets 挂载或外部加密存储,绝不见明文13。
  7. 运行时靠 Falco/Sysdig 看行为,补静态防线之盲区14。

8. 原文地图

主题 原书章 原文位置
攻击面与全生命周期立场 Chapter 13: Securing Containers text/144-ch13-chapter-13-securing-containers.txt:4(搜「attack surface」)
三层纵深(扫描/签名/执行) Container hardening practices text/147-fm-container-hardening-practices.txt:1(搜「signature verification」) · text/147-fm-container-hardening-practices.txt:3(搜「admission controllers」) · text/147-fm-container-hardening-practices.txt:8(搜「defense-in-depth」)
加固定义与清单 Container hardening practices text/147-fm-container-hardening-practices.txt:13(搜「Container hardening」) · text/147-fm-container-hardening-practices.txt:17(搜「tightening」)
非 root 与 capability Container hardening practices text/147-fm-container-hardening-practices.txt:28(搜「least privilege」) · text/147-fm-container-hardening-practices.txt:40(搜「groupadd」) · text/147-fm-container-hardening-practices.txt:58(搜「cap-drop ALL」) · text/147-fm-container-hardening-practices.txt:67(搜「don't include it」)
--no-new-privileges Container hardening practices text/147-fm-container-hardening-practices.txt:68(搜「no-new-privileges」) · text/147-fm-container-hardening-practices.txt:79(搜「simple but powerful」)
只读文件系统与最小挂载 Container hardening practices text/147-fm-container-hardening-practices.txt:93(搜「read-only」) · text/147-fm-container-hardening-practices.txt:110(搜「logs」)
最小镜像与多阶段 Container hardening practices text/147-fm-container-hardening-practices.txt:113(搜「minimal images」) · text/147-fm-container-hardening-practices.txt:118(搜「distroless」) · text/147-fm-container-hardening-practices.txt:126(搜「intermediate layers」)
seccomp/AppArmor/SELinux/userns Container hardening practices text/147-fm-container-hardening-practices.txt:129(搜「Kernel-level」) · text/147-fm-container-hardening-practices.txt:135(搜「seccomp」) · text/147-fm-container-hardening-practices.txt:137(搜「AppArmor」) · text/147-fm-container-hardening-practices.txt:140(搜「User namespaces」) · text/147-fm-container-hardening-practices.txt:143(搜「privileged」) · text/147-fm-container-hardening-practices.txt:146(搜「icc=false」)
资源限额作为安全手段 Container hardening practices text/147-fm-container-hardening-practices.txt:158(搜「Resource limits」) · text/147-fm-container-hardening-practices.txt:166(搜「denial-of-service」)
HEALTHCHECK 与不可变替换 Container hardening practices text/147-fm-container-hardening-practices.txt:171(搜「HEALTHCHECK」) · text/147-fm-container-hardening-practices.txt:188(搜「replace it」)
组合基线 Container hardening practices text/147-fm-container-hardening-practices.txt:191(搜「Putting it all together」) · text/147-fm-container-hardening-practices.txt:200(搜「--read-only」) · text/147-fm-container-hardening-practices.txt:213(搜「strong baseline」)
加固代价表 Container hardening practices text/147-fm-container-hardening-practices.txt:215(搜「Trade-offs」) · text/148-fm-secrets-management.txt:1(搜「Potential Downsides」)
secrets 挂载 Secrets management text/149-fm-runtime-security-tools.txt:7(搜「/run/secrets/db_password」) · text/149-fm-runtime-security-tools.txt:5(搜「docker compose up」)
运行时 Falco Runtime security tools text/150-fm-summary.txt:1(搜「stale」) · text/141-fm-observability-and-security-monitoring.txt:31(搜「Falco」)

  1. 出处:「Chapter 13: Securing Containers」第 1–16 段(text/144-ch13-chapter-13-securing-containers.txt:4,搜「attack surface」)与「Supply chain security」的安装步骤(text/145-fm-supply-chain-security.txt:1,搜「Installing Trivy」)。 ↩↩

  2. 出处:「Supply chain security」第 1–20 段(text/145-fm-supply-chain-security.txt:5,搜「official binaries」;:3,搜「WSL2」)。 ↩

  3. 出处:「Image vulnerability scanning and content trust」第 1–10 段(text/146-fm-image-vulnerability-scanning-and-content-trust.txt:2,搜「floating tag」;:3,搜「cosign generate-key-pair」)。 ↩↩

  4. 出处:「Container hardening practices」第 1–11 段(签名执行段因转码顺序位于本文件开头:text/147-fm-container-hardening-practices.txt:1,搜「signature verification」;:3,搜「Connaisseur」;:8,搜「defense-in-depth」;:11,搜「cannot enter production」)。 ↩↩↩

  5. 出处:「Container hardening practices」第 13–26 段(text/147-fm-container-hardening-practices.txt:17,搜「tightening」;:18,搜「attack surface」)。 ↩

  6. 出处:「Container hardening practices」第 28–86 段(text/147-fm-container-hardening-practices.txt:29,搜「run as root」;:40,搜「groupadd -r」;:42,搜「USER appuser」;:58,搜「cap-drop ALL」;:67,搜「don't include it」;:69,搜「escalate privileges」;:83,搜「alternative」)。 ↩↩↩↩

  7. 出处:「Container hardening practices」第 88–127 段(text/147-fm-container-hardening-practices.txt:99,搜「--read-only」;:105,搜「writable volumes」;:113,搜「minimal images」;:118,搜「distroless」;:121,搜「multi-stage」;:126,搜「intermediate layers」)。 ↩↩

  8. 出处:「Container hardening practices」第 129–156 段(text/147-fm-container-hardening-practices.txt:135,搜「seccomp filters」;:137,搜「AppArmor and SELinux」;:140,搜「User namespaces」;:143,搜「privileged mode」;:146,搜「--icc=false」;:152,搜「seccomp=default.json」)。 ↩↩

  9. 出处:「Container hardening practices」第 158–166 段(text/147-fm-container-hardening-practices.txt:162,搜「--memory」;:166,搜「denial-of-service」)。 ↩↩

  10. 出处:「Container hardening practices」第 168–189 段(text/147-fm-container-hardening-practices.txt:172,搜「HEALTHCHECK」;:177,搜「retries=3」;:188,搜「replace it」)。 ↩↩

  11. 出处:「Container hardening practices」第 191–213 段(text/147-fm-container-hardening-practices.txt:196,搜「hardening flags」;:200,搜「--read-only」;:213,搜「strong baseline」)。 ↩↩

  12. 出处:「Container hardening practices」第 215 段起与「Secrets management」开头的代价表(text/147-fm-container-hardening-practices.txt:216,搜「every restriction」;text/148-fm-secrets-management.txt:1,搜「Potential Downsides」)。 ↩↩↩

  13. 出处:「Secrets management」与「Runtime security tools」的演示(因转码顺序位于文件 149:text/149-fm-runtime-security-tools.txt:5,搜「docker compose up」;:5,搜「/run/secrets/db_password」)。 ↩↩

  14. 出处:「Runtime security tools」(text/150-fm-summary.txt:1,搜「stale」)与「Observability and security monitoring」的运行时监控段(text/141-fm-observability-and-security-monitoring.txt:31,搜「Falco」)。 ↩↩