跳转至

Docker 安全

容器边界弱于虚拟机,因为共享宿主机内核。安全目标是降低镜像、运行权限、Docker API、网络和供应链任一环节失陷后的影响范围。

首要风险

风险 处理原则
Docker Socket 暴露 不挂入普通容器,不裸露未认证 TCP API
容器以 root 运行 镜像创建专用 UID/GID,运行时只读和最小权限
--privileged 默认禁止,仅对已评审的基础设施组件使用
主机目录写挂载 缩小路径并优先 :ro,禁止挂载 /
镜像漏洞/投毒 可信来源、固定版本/Digest、扫描、签名和 SBOM
Secret 泄露 不写 Dockerfile、ENV、镜像层和普通 Git

最小权限运行

docker run -d --name app \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --cap-drop ALL \
  --security-opt no-new-privileges=true \
  --user 10001:10001 \
  --pids-limit 200 \
  --memory 512m \
  --cpus 1 \
  registry.example.com/app:1.4.0

先全部删除 Capability,再按确切需求添加。不要遇到 Permission denied 就改为 root、--privileged 或关闭 seccomp;先确认文件 UID/GID、只读文件系统、Capability、SELinux/AppArmor 和系统调用限制。

Docker 默认 seccomp 配置会限制部分危险系统调用,官方不建议无理由改为 seccomp=unconfined。Rootless 模式让 dockerd 和容器在用户命名空间中运行,可降低守护进程漏洞风险,但网络、存储、特权端口和 cgroup 能力存在不同限制,应先验证应用。

Docker Socket

能访问 /var/run/docker.sock 的进程通常可以创建特权容器、挂载主机目录,从而控制宿主机。不要把 Socket 挂给监控、CI 或 Web 管理工具,除非明确评估其权限;若必须使用,采用隔离主机、受限代理和审计。

Secret

构建时不要使用 ARG TOKENENV TOKEN,这些值可能进入镜像历史或元数据。BuildKit 使用临时 Secret Mount:

# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
    npm ci
docker build --secret id=npmrc,src=.npmrc -t app:1.0.0 .

运行时 Secret 使用受限只读文件、Compose Secret 或外部 Secret 系统,并建立轮换和吊销流程。环境变量可能出现在 inspect、Dump 或错误报告中,不适合所有高敏感凭据。

主机与网络

  • Docker 主机只运行容器工作负载,减少无关软件和登录用户。
  • 及时更新内核、Docker Engine、containerd 和镜像基础层。
  • 防火墙规则必须验证 Docker 发布端口后的实际效果。
  • 数据库和管理端口只绑定内网或 127.0.0.1
  • 生产、测试和不可信工作负载按主机或更强边界隔离。

官方参考:Docker Engine securityRootless modeSeccomp