Skip to content

Docker 安全 ​

1. 威胁面 ​

至少考虑:

  • 不可信镜像和依赖;
  • 被攻陷的容器尝试横向或逃逸;
  • Docker socket/daemon API 滥用;
  • 危险挂载、设备和 capabilities;
  • Registry 凭据、构建 Secret 泄露;
  • 共享内核和宿主机漏洞;
  • 过度网络暴露和资源耗尽。

2. Daemon 边界 ​

Docker daemon 通常拥有高权限。禁止:

  • 明文暴露 tcp://0.0.0.0:2375;
  • 把 /var/run/docker.sock 挂载进普通业务容器;
  • chmod 666 socket;
  • 给不可信用户 docker 组权限。

远程管理优先 SSH Context:

bash
docker context create prod \
  --docker 'host=ssh://ops@example.internal'
docker --context prod info

3. 非 root 与 Rootless ​

镜像:

dockerfile
RUN addgroup -S app && adduser -S -G app -u 10001 app
USER 10001:10001

运行:

bash
docker run --rm --user 10001:10001 team-api:latest id

高风险或多租户场景评估 Rootless Docker/user namespace。非 root 不会自动抵消危险挂载或内核漏洞。

4. 最小 capabilities ​

基线:

bash
docker run -d \
  --cap-drop ALL \
  --security-opt no-new-privileges=true \
  team-api:latest

只添加实际需要的能力:

bash
docker run -d \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  team-proxy:latest

不要用 --privileged 解决普通权限错误。它显著移除隔离,应限于受控基础设施组件并经过安全评审。

5. Seccomp 与 LSM ​

Docker 默认 seccomp profile 会阻止一部分危险系统调用,官方不建议随意关闭:

bash
docker info | sed -n '/Security Options/,+10p'

自定义:

bash
docker run --security-opt seccomp=./profile.json app:latest

避免:

bash
docker run --security-opt seccomp=unconfined app:latest

AppArmor/SELinux 应保持启用;遇到拒绝先查审计日志并最小化授权,不要关闭整个机制。

6. 文件系统 ​

bash
docker run -d \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --mount type=volume,src=app-data,dst=/app/data \
  team-api:latest
  • bind mount 默认可写;除非明确需要写,使用 readonly 或 ro 显式设为只读。
  • 不挂载宿主根目录、/proc、/sys、设备目录。
  • 只提供所需设备,不用 --privileged。

7. Secret ​

不要把 Secret 放入:

  • Dockerfile ARG/ENV;
  • 镜像层;
  • Git 中的 Compose/env 文件;
  • 命令行参数;
  • 普通容器环境变量(能用文件/短期身份时)。

构建使用 BuildKit:

bash
docker buildx build \
  --secret id=npmrc,src="$HOME/.npmrc" .

运行时使用组织批准的 Secret manager,设置最小读取权限、轮换和撤销流程。

8. 供应链 ​

bash
docker buildx build \
  --pull \
  --sbom=true \
  --provenance=mode=max \
  -t "$IMAGE_REF" \
  --push .

发布门禁:

  1. base image 和依赖锁定;
  2. 单元/集成测试;
  3. 漏洞和恶意软件扫描;
  4. SBOM/provenance;
  5. 签名 digest;
  6. 部署侧验证策略;
  7. 高危例外有所有者和到期日。

生产按 digest 部署,tag 设为不可变。

9. 网络 ​

  • 默认不发布端口。
  • 仅本地消费时绑定 127.0.0.1。
  • 前端、后端和管理网络分隔。
  • 使用 TLS 和应用认证,不能只信任“同一 bridge”。
  • 在安全组和 DOCKER-USER chain 验证真实入口策略。

10. 资源与拒绝服务 ​

bash
docker run -d \
  --memory 512m \
  --cpus 1 \
  --pids-limit 256 \
  --ulimit nofile=65536:65536 \
  team-api:latest

限制需经压测。配合日志轮转,避免磁盘耗尽。

11. 主机基线 ​

  • 使用受支持的 Linux/Engine 版本并及时修复安全公告。
  • 专用容器主机,减少无关服务。
  • 时间同步、审计、EDR/主机监控按组织策略启用。
  • /var/lib/docker、socket、配置和证书权限正确。
  • 备份加密,恢复演练。
  • 避免在同一 daemon 混跑高信任和不可信工作负载。

12. 安全检查命令 ​

bash
docker info
docker ps --format '{{.Names}}\t{{.Image}}\t{{.Ports}}'
docker inspect CONTAINER \
  --format 'user={{.Config.User}} privileged={{.HostConfig.Privileged}} readonly={{.HostConfig.ReadonlyRootfs}} caps={{json .HostConfig.CapAdd}} mounts={{json .Mounts}}'
docker image inspect IMAGE --format '{{.Config.User}}'
docker history --no-trunc IMAGE

查 socket 挂载:

bash
docker ps -q | xargs -r docker inspect \
  --format '{{.Name}} {{json .Mounts}}' \
  | grep docker.sock

13. 高危配置清单 ​

  • --privileged
  • --network host
  • --pid host / --ipc host
  • --cap-add ALL
  • seccomp=unconfined
  • /var/run/docker.sock 挂载
  • 宿主 /、/proc、/sys 可写挂载
  • daemon 2375 无 TLS
  • 容器 root + 可写根文件系统
  • 不限 CPU/内存/PID/日志
  • 浮动 tag 直接生产部署

发现这些配置不应直接删除;先确认业务依赖,设计最小替代并回归测试。

14. 事件响应 ​

容器疑似失陷时:

  1. 从负载均衡摘流或隔离网络;
  2. 保存时间、容器 ID、镜像 digest、inspect、日志和 events;
  3. 不在缺乏取证计划时随意重启/删除;
  4. 撤销相关 token、证书和云身份;
  5. 从可信源码和基线重建,不“修补”旧容器;
  6. 检查宿主机、同节点容器和 Registry;
  7. 完成根因、范围、恢复和防复发。

15. 官方参考 ​

继续阅读