内容提要
Docker采用客户端-服务器架构,守护进程以root运行,存在权限提升风险。用户常加入docker组以便使用,但这使非root用户可能获取root权限。文章建议采用rootless模式或使用Podman等替代方案,并讨论了Podman的兼容性问题及解决方案。
延伸解读
风险根源:客户端-服务器架构与权限配置
Docker 的安全问题源于其客户端-服务器架构,守护进程以 root 运行,并通过 API 提供功能。默认安装下,docker 命令仅限 root 使用,但用户常为方便而将自己加入 docker 组,这使任何非 root 用户都能通过挂载宿主机文件系统等方式获取 root 权限。文章演示了无需密码即可读取 /etc/sudoers.d/ 目录,说明该风险并非理论,而是实际可操作的。
Podman 的兼容性差异与应对
Podman 作为无守护进程的替代方案,多数工作流可无缝切换,但存在差异:默认镜像仓库可能不是 Docker Hub,导致 docker pull postgres 失败,需使用完整镜像地址如 docker.io/library/postgres。此外,无守护进程意味着重启后容器不会自动恢复,需借助 systemd 集成(如 quadlet)管理;若需 API,可启动 podman system service,但仅对当前用户有效。
macOS 与 Windows 上的风险差异
Docker 仅原生运行于 Linux,在 macOS 和 Windows 上通过虚拟机(如 QEMU、Hyper-V)实现,额外隔离层降低了宿主机风险。但 Windows 的 WSL 因 Linux 内核直接运行在宿主机上,集成更紧密,可能面临与 Linux 系统类似的风险。文章作者对此领域了解有限,邀请有经验者补充细节。
Q&A
Docker 存在哪些安全风险?
Docker 采用客户端-服务器架构,守护进程以 root 权限运行,如果用户加入 docker 组或放宽 socket 权限,非 root 用户可能通过 docker 命令获取 root 权限,导致权限提升攻击。
如何演示 Docker 的权限提升漏洞?
在将用户加入 docker 组后,运行 `docker run -v /:/host alpine:latest ls /host/etc/sudoers.d/` 可以读取宿主机上通常无权限访问的文件,因为容器以 root 权限运行并挂载了宿主机文件系统。
为什么用户会将自己加入 docker 组?
因为默认情况下 docker 命令需要 root 权限,使用 sudo 不方便,所以用户为了免 sudo 运行 docker 命令,会将自己加入 docker 组,但这带来了安全风险。
Docker 在 macOS 和 Windows 上是否安全?
Docker 在 macOS 和 Windows 上通过虚拟机运行,增加了隔离层,风险较低;但 WSL 与系统集成紧密,风险类似 Linux。
什么是无根容器?有哪些实现方式?
无根容器是指容器进程不以 root 身份运行,实现方式包括 Docker 的 rootless 模式和 Podman。Docker rootless 模式需要额外配置,而 Podman 无需守护进程,安装即可使用。
Podman 与 Docker 相比有哪些优缺点?
Podman 无需守护进程,更安全,但默认镜像仓库可能不同,需要指定完整镜像名;且无法自动重启容器,需要借助 systemd 集成。
如何解决 Podman 拉取镜像失败的问题?
可以配置默认仓库,或使用完整镜像名,例如 `podman pull docker.io/library/postgres`。
Podman 如何实现容器开机自启?
Podman 通过 systemd 集成(podman quadlet)将容器安装为系统服务,实现开机自启。
Podman 如何提供 API 服务?
Podman 可以通过 `podman system service` 命令启动一个用户级 API 服务,该服务与 Docker API 兼容,也可通过 systemd 集成常驻后台。