启用--read-only参数可将容器根文件系统挂载为只读,从内核VFS层拦截所有写操作;需配合--tmpfs提供内存级可写路径(如/tmp)、--cap-drop=ALL禁用高危能力,并在宿主机侧对bind mount文件执行chattr +i实现双重防护。
只读文件系统本身不能直接防止容器内恶意程序篡改核心二进制文件——因为默认情况下,docker 容器的根文件系统(rootfs)是可写的。真正起作用的是主动启用 --read-only 运行时参数,它会将整个容器根文件系统挂载为只读,从内核 vfs 层拦截所有写操作,包括覆盖、删除、重命名等行为。
必须用 --read-only 启动容器
这是最基础也最关键的一步。不加该参数,即使镜像层本身不可变,容器运行时仍会叠加一个可写的容器层(如 overlay2 的 upperdir),恶意程序可随意修改 /bin、/usr/bin 下的二进制文件。
- 命令示例:
docker run --read-only -it ubuntu:22.04 - 此时尝试执行
echo 'bad' > /bin/ls会立即报错:Read-only file system - 注意:启用后,/proc、/sys、/dev 等虚拟文件系统仍需显式挂载,否则容器可能无法启动
配合 tmpfs 挂载必要可写路径
--read-only 会禁止一切写入,但某些路径必须可写才能正常运行(如 /tmp、/run、/var/run)。若不处理,服务会因权限失败而崩溃。
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
- 使用
--tmpfs为这些路径提供内存级可写空间:--tmpfs /tmp:rw,noexec,nosuid,size=32m - 也可在 docker-compose.yml 中配置:
tmpfs: - /run - /tmp - tmpfs 数据驻留内存、重启即清空,既满足运行需求,又避免磁盘残留和持久化篡改
禁用高危 capability 并限制挂载能力
即使根文件系统只读,攻击者仍可能通过提权获得 mount 权限,重新挂载 rootfs 为可写。因此必须移除相关系统能力:
- 禁用
cap_sys_admin(绝大多数挂载操作依赖此能力) - 显式丢弃高危能力:
--cap-drop=ALL --cap-add=NET_BIND_SERVICE - 添加
--security-opt no-new-privileges:true防止进程通过 execve 提权获取新权限
对关键路径做双重保护:只读挂载 + chattr +i(宿主机侧)
如果二进制文件来自宿主机 bind mount(例如替换某个工具链),仅靠容器 --read-only 不够——攻击者可能逃逸到宿主机再修改源文件。此时应在宿主机上锁定:
- 对宿主机上的原始二进制文件执行:
chattr +i /host/path/to/binary - 该操作需 root 权限,且内核级生效,连 root 用户也无法修改或删除,除非先
chattr -i - 适用于极少数强管控场景,如信创环境中的定制化守护进程

















