首页 > 解决方案 > Docker userns-remap 用户拥有的文件最终由容器内的任何人拥有

问题描述

我正在搞乱 Docker 用户命名空间重新映射:https ://docs.docker.com/engine/security/userns-remap/

我通过修改/etc/docker/daemon.json. 内容目前如下所示:

{
  "userns-remap": "default"
}

我已经重新启动了 Docker 守护进程。默认dockremap用户是按照文档的承诺创建的:

user@host:~$ id dockremap
uid=125(dockremap) gid=134(dockremap) groups=134(dockremap)

中还有一个条目/etc/subuid

dockremap:165536:65536

现在,我有一个包含共享文件的文件夹,我希望将其绑定安装在容器中以使其可供读取。在主机操作系统上,该文件具有以下所有者和权限设置:

-rwxrwx--- 1 dockremap dockremap 0 april 8 19:19 shared_file.txt

该文件不应该是世界可写的。我的实际意图是在主机操作系统和容器之间安全地共享一个包含一些秘密信息的文件。

如果父目录有任何区别,则它是全局可写的:

drwxrwxrwx 3 dockremap dockremap 4,0K april 8 19:20 .

我将它绑定安装到一个 Alpine 容器中,如下所示:

docker run --rm -it -w /work -v $(pwd)/shared_file.txt:/work/shared_file.txt remaptest ls -lah

我现在希望该文件由root容器内的 UID 0 拥有,因此可以读取。相反,它归以下所有nobody且不可读root

-rwxrwx--- 1 nobody nobody 0 Apr 8 16:19 shared_file.txt

nobody容器内有以下 id:

/work # id nobody
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)

我是否对用户命名空间重新映射和绑定挂载文件系统权限如何协同工作有错误的期望,或者这里有什么问题?我已经在两台不同的 PC 上对此进行了测试。其中一个运行 Ubuntu,另一个运行 Mint。

我还用Ubuntu-based容器而不是容器进行了测试Alpine-based,但结果几乎相同。我当然可以修改用于构建映像的 Dockerfile,但我的印象是我在上面执行此操作的方式应该可行。

我想使用它的实际Dockerfile来自 Docker Hub,我不想弄乱它的设置方式。

标签: dockerlinux-namespaces

解决方案


首先让我说,在我自己非常有限的经验中,我发现用户命名空间映射是一个特别难以理解的主题,尤其是在使用 docker 时。我个人觉得,有错误的期望几乎是设计使然。但它仍然是一个强大的工具。

怎么了?

在你的情况下,我会尝试安装$(pwd)到容器中/work(而不仅仅是文件)并运行touch /work/test.txt. 在您的主机上,您将看到该文件是由具有 uid 的用户在165536您运行时创建的ls -lan $(pwd)。正如您的主机/etc/subuid文件中所述,但我同意这不一定是您所期望的。

可以做什么?

为了解决这个问题,我会在/etc/subuid. 例如,您可以在 之前添加一行dockremap:165536:65536,说明dockremap:125:1。由于dockremap您主机上的 uid 是125并且您只想映射这个 uid,因此这一行应该可以解决问题。

现在,如果您touch使用新文件再次进行测试,您将看到您的文件在主机上由(aka 125)拥有,在容器中由 (aka ) 拥有。dockremap0root

进一步阅读

我可以推荐这篇文章:https ://www.jujens.eu/posts/en/2017/Jul/02/docker-userns-remap/


推荐阅读