不少团队在等保测评整改时会遇到一个尴尬局面:宿主机的加固项一条条都落实了,可测评机构扫到 Docker 环境时,整改单上依然多出一串问题——容器用 root 在跑、daemon 暴露了明文管理端口、镜像来源说不清。等保 2.0(GB/T 22239-2019)并没有给容器单独发一份 checklist,安全计算环境的通用控制点加上云计算、容器安全扩展要求,需要运维自己翻译成 Docker 语言,而翻译的偏差往往就是扣分点。
这篇文章做的就是这个翻译工作。把容器相关的合规要求归纳为"身份可信、镜像可信、运行受控、数据不留痕"四个维度,每个配置项都对应到等保 2.0 的具体控制点,最后汇总成一张可以直接拿去自查的清单。范围只覆盖 Docker 引擎与容器层,不涉及 K8s 集群级别的网络策略。

身份可信:先管住"谁能碰 Docker"
等保 2.0 安全计算环境下的"身份鉴别"和"访问控制"控制点,落到 Docker 上第一件事是认清一个事实:能访问 Docker daemon 的人,等价于拿到了宿主机 root。因为通过 daemon socket 随时可以启动一个挂载宿主机根目录的特权容器,所以 docker 用户组的成员名单本身就是一份访问控制策略,而不是图方便的授权方式。
具体要做三件事。一是收敛本地访问,把确实需要操作容器的账号加进 docker 组,其余账号一律走 sudo 并保留命令审计记录,定期核对组内是否存在"历史遗留"账号。二是管住远程管理通道,容器安全扩展要求里明确应对容器实例的访问请求进行身份标识和鉴别,并确保使用安全协议连接——确实需要远程管理 daemon 时,必须启用 TLS 双向认证(--tlsverify,走加密的 2376 端口),客户端与服务端互验证书;直接把 tcp://0.0.0.0:2375 这种明文无认证端口暴露在内网,测评时基本就是一条必开的整改项。三是留存操作痕迹,等保的"安全审计"控制点要求审计记录覆盖到每个用户,容器标准同样要求镜像仓库的访问日志保存并定期审查,因此 daemon 操作日志、registry 的推送拉取日志都要集中收集,而不是留在本机随容器生命周期一起消失。
镜像可信:用 cosign 把"来源可查"变成硬约束
等保 2.0 云计算安全扩展要求中专门包含"镜像和快照保护"的内容,容器安全要求也提出应采用密码技术保护容器镜像。翻译过来就是:你要能证明生产环境运行的镜像,就是 CI 构建出来的那一个,中间没被掉包,也不是谁随手 push 上去的。
cosign(Sigstore 项目)是目前最顺手的签名工具,它针对镜像 digest 生成和校验签名。基本链路分三步:
- 用
cosign generate-key-pair生成密钥对,私钥放进 CI 的凭据管理体系,公钥分发给需要部署验证的环境; - CI 构建并推送镜像后执行签名,推荐按 digest 签而不是按 tag 签,避免 tag 被复用后签名指向发生漂移;
- 部署前执行
cosign verify校验签名与公钥,验证不通过就直接拒绝上线。
# CI 中:构建推送后对镜像签名(按 digest)
cosign sign --key cosign.key registry.example.com/app@sha256:9f2c...
# 部署前:验证签名,失败则终止发布
cosign verify --key cosign.pub registry.example.com/app@sha256:9f2c...

需要注意,签名只是"来源可信"的一半,另一半是镜像内容本身:基础镜像固定到 digest 而不是 floating 的 latest,推入仓库前过一遍漏洞扫描,私有仓库开启访问认证。这些对应的同样是镜像保护条款,测评时会被一并问到。关于容器镜像保护的完整条款背景,可以参考《网络安全等级保护容器安全要求》标准解读。
运行受控:禁用 privileged 与细粒度 capability
这是整改中最容易踩坑的部分,对应等保"访问控制"的最小权限原则和"入侵防范"控制点。容器安全扩展要求里有一条写得很直白:应在镜像构建配置文件中将运行用户定义为非最高权限用户,禁止未定义用户或定义为最高权限用户。也就是说 Dockerfile 里必须有明确的 USER 指令,容器内进程不能以 root 运行,评测方法就包括检查 Dockerfile 配置和模拟攻击者利用特权用户控制容器。
但 USER 只是第一层。即使容器内是非 root 用户,--privileged 一开就前功尽弃:特权容器会拿到全部 linux capabilities 和宿主机设备访问权,容器内 root 与宿主机 root 之间几乎没有边界。合规姿势是全面禁用 privileged 模式,然后用 capability 机制做细粒度授权。linux 把 root 的权限拆成了几十个 capability,例如绑定低端口的 NET_BIND_SERVICE、修改文件属主的 CHOWN 等,Docker 默认会给容器一组相对保守的 capability,但对多数业务来说仍然偏大。稳妥做法是先全部砍掉,再按业务需要逐项加回:
docker run -d
--user 10001:10001
--cap-drop=ALL
--cap-add=NET_BIND_SERVICE
--security-opt no-new-privileges:true
--read-only
registry.example.com/app@sha256:9f2c...
这一条命令同时落实了四个控制点:非 root 运行对应容器扩展的用户要求,--cap-drop=ALL 加按需 --cap-add 对应最小权限,no-new-privileges 防止进程通过 setuid 类机制提权,--read-only 让根文件系统只读、攻击者无法落地工具。在此之上还可以叠加 Docker 默认自带的 seccomp profile,以及内存、PID 数量等资源限制,防止单个容器被攻破后耗尽宿主机资源,这对应"入侵防范"中的资源控制要求。
落地时的现实建议是:先在测试环境用 --cap-drop=ALL 把服务跑起来,观察应用报什么错、实际缺什么能力,再逐项加回。通常一个普通的 Web 服务只需要一两个 capability 就能正常工作,直接照抄网上的权限清单,往往会加回一堆根本用不到的能力。
数据不留痕:敏感数据不残留,审计日志要留存
这个维度对应等保的"数据保密性"要求,以及容器标准中防止镜像内敏感资源被非法访问的条款。它有正反两面,整改时别做反了。
一面是敏感数据不能残留。最常见的事故是密钥进镜像层:构建时 COPY 进去的证书、写在 Dockerfile 里的数据库密码,即使后面用一层 RUN rm 删掉,文件依然躺在历史层里,通过 docker history 或导出镜像就能翻出来。正确姿势是 secret 不进镜像——构建期使用 BuildKit 的 secret mount,运行期通过挂载文件或密钥管理服务注入;用 .dockerignore 把 .git、本地配置挡在构建上下文之外;多阶段构建只把最终产物拷进运行镜像。运行期产生的敏感临时文件用 --tmpfs 挂到内存里,容器停止即消失;数据卷在容器删除后要有明确的清理或归档策略,不能放任残留。
另一面是审计数据必须留存。容器的 stdout 日志、daemon 日志、registry 访问日志要集中外送到日志系统,而不是只存在容器本地。《网络安全法》要求相关网络日志留存不少于六个月,等保测评同样会核查日志的完整性和保存周期。"数据不留痕"指的是敏感业务数据不残留,绝不是把审计痕迹一起抹掉。
落地检查清单
把上面四个维度汇总成一张自查表,每一行都可以直接拿去核对现有环境:
| 维度 | 检查项 | 合规配置要点 | 对应等保 2.0 要求 |
|---|---|---|---|
| 身份可信 | docker 组成员 | 成员最小化,其余操作走 sudo 留痕 | 访问控制 |
| 身份可信 | daemon 远程访问 | TLS 双向认证,禁用明文 2375 端口 | 身份鉴别与安全协议连接 |
| 身份可信 | 操作日志 | daemon、registry 日志集中收集并定期审查 | 安全审计 |
| 镜像可信 | 镜像签名 | cosign 按 digest 签名,部署前 verify,不过不发布 | 镜像和快照保护 |
| 镜像可信 | 镜像内容 | 基础镜像固定 digest,入库前漏洞扫描,仓库开启认证 | 镜像和快照保护 |
| 运行受控 | 运行用户 | Dockerfile 明确 USER,禁止 root 或未定义用户 | 容器扩展-非最高权限用户 |
| 运行受控 | 特权模式 | 全面禁用 --privileged | 访问控制-最小权限 |
| 运行受控 | capability | cap-drop=ALL 后按业务逐项 cap-add | 访问控制-最小权限 |
| 运行受控 | 提权与文件系统 | no-new-privileges、read-only、默认 seccomp、资源限制 | 入侵防范 |
| 数据不留痕 | 镜像内敏感数据 | secret 不进镜像层,dockerignore 加多阶段构建 | 数据保密性 |
| 数据不留痕 | 运行时敏感数据 | tmpfs 挂载临时文件,卷有清理归档策略 | 数据保密性 |
| 数据不留痕 | 日志留存 | 容器与访问日志外送,留存周期满足法规要求 | 安全审计 |
建议的使用方式是:先拿这张清单对现有环境做一轮基线自查,标记出不达标项;然后把其中的硬约束——cosign 验签、capability 配置、非 root 运行——直接写进 CI/CD 流水线和部署模板,让合规从"测评前突击"变成"每次发布自动过关"。等测评机构问起来的时候,你能直接拿出配置记录、审计日志和签名验证结果,这比任何口头解释都有说服力。

重庆市 1F
这份清单太及时了,正准备应对等保测评