
直接加 --read-only 是最简方式,但必须配套为关键路径提供可写空间,否则容器大概率启动失败或运行异常。只读根文件系统本身不能“单独防逃逸”,它要和非 root 用户、能力限制、镜像精简等措施一起,才能真正压缩攻击面。
启用只读根并验证生效
启动时加上 --read-only 参数,整个 / 就会被挂载为只读:
docker run --read-only -it alpine sh
进容器后执行:
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
-
mount | grep "on / type"—— 输出中应含ro -
touch /test—— 应报错Read-only file system
必须挂载可写临时路径(tmpfs)
nginx、supervisord、Java 应用等都会往 /tmp、/run、/var/run 写 PID、socket、锁或临时解压包。不处理就会崩溃。推荐用 tmpfs,内存驻留、重启即清、无持久风险:
--tmpfs /tmp:rw,size=10M--tmpfs /run:rw,size=5M--tmpfs /var/run:rw,size=5M- 如需本地日志,可加
--tmpfs /var/log:rw,但更建议应用改用 stdout/stderr
按需挂载可写数据卷(严格限定路径与权限)
只在真正需要持久化或共享时才挂载,且必须显式声明:
- 上传目录:
-v upload-data:/app/uploads:rw(命名卷,推荐) - 缓存数据(如 Redis AOF):
-v redis-data:/data:rw - 证书/配置/静态资源:
-v cert-volume:/etc/tls:ro(用:ro明确禁止写入) - 禁用 bind mount 宿主机敏感路径(如
/etc、/root),尤其避免:z或:ZSELinux 标签
协同其他最小权限机制
只读根只是纵深防御的一环,还需同步落地:
- 丢弃默认能力:
--cap-drop=ALL --cap-add=NET_BIND_SERVICE(仅保留业务必需) - 强制非 root 运行:
--user 1001:1001,并在 Dockerfile 中固化USER指令 - Kubernetes 场景下,在
securityContext统一设readOnlyRootFilesystem: true、runAsNonRoot: true、capabilities.drop - 构建阶段清理:
RUN apt clean && rm -rf /var/lib/apt/lists/*,删调试工具和缓存

















