最可靠的方式是通过 runtimeArgs 在容器运行时层面锁定 rootfs 只读,即配置 daemon.json 启用 "--no-pivot" 和 "--no-new-privs",从引擎层禁用 pivot_root 与提权,比 --read-only 更彻底。
直接在容器启动时强制根文件系统为只读,最可靠的方式不是靠挂载卷或镜像层控制,而是通过
runtime 参数(runtimeArgs)
在容器运行时层面锁定整个 rootfs 的可写性。这比仅用
命令行参数更底层、更不可绕过——尤其在 Docker 27+ 和 runc v1.2+ 环境下,它已深度集成进默认安全策略。
核心机制:--no-pivot + --no-new-privs 是关键组合
Docker 本身不直接暴露
这类底层 runc 参数,但可通过 daemon 级配置注入。它的作用是禁用
系统调用,从而阻止容器在启动后切换根目录或重新挂载文件系统,配合
(禁止提权),能真正封死 rootfs 被动态改为可写的路径。
:防止容器内进程执行
或
类操作,避免绕过只读限制
:确保进程及其子进程无法通过 setuid/setgid 或 file capabilities 获取额外权限,切断提权改写 rootfs 的可能
二者协同,比单纯
更彻底——后者仅挂载时设为 ro,而前者从运行时引擎层掐断所有修改 rootfs 的能力链
配置方式:修改 /etc/
docker
/daemon.json
这不是容器启动命令里的临时参数,而是守护进程级的默认行为。将以下内容写入
:
保存后执行:
此后所有新启动的容器(除非显式覆盖 runtime)都会自动启用该加固模式。注意:
要求宿主机内核支持(Linux ≥ 3.18),且基础镜像需兼容(如 Alpine、Distroless 均适配)。
Docker Sandbox
创建并管理 Docker 沙箱虚拟机环境以安全执行代理。适用于运行不受信任代码、探索包或隔离代理工作负载。支持 Claude、Codex、Copilot、Gemini 和 Kiro 代理,并提供网络代理控制。
下载
验证是否生效
启动一个测试容器:
若输出中包含
且无
,说明根挂载已是只读;再检查是否真的无法提权:
预期返回
—— 即使加了高危 capability,也无法突破只读根文件系统。
补充建议:与其它安全选项协同使用
单独启用
不够全面。推荐搭配以下配置形成纵深防御:
:仍保留在
命令中,作为显式声明和兼容性保障
:与 daemon 配置中的
形成双重确认
:按需最小化 capability,避免因能力残留导致逃逸
使用 Distroless 或
基础镜像:从源头移除 shell 和包管理器,进一步压缩攻击面
--read-only--no-pivotpivot_root--no-new-privs--no-pivotpivot_rootchroot--no-new-privs--read-only/etc/docker/daemon.json{
"default-runtime": "runc",
"runtimes": {
"runc": {
"path": "runc",
"runtimeArgs": [
"--no-pivot",
"--no-new-privs"
]
}
}
}sudo systemctl restart docker--no-pivotdocker run -it --rm alpine sh -c 'mount | grep " / " 'ro,relatimerwdocker run -it --rm --cap-add=SYS_ADMIN alpine sh -c 'touch /test && echo "write succeeded"'touch: /test: Read-only file system--no-pivot--read-onlydocker run--security-opt no-new-privileges--no-new-privs--cap-drop=ALL --cap-add=NET_BIND_SERVICEnonroot