使用用户命名空间隔离容器 | Isolate containers with a user namespace (Engine)
Linux名称空间为正在运行的进程提供了隔离,限制了它们对系统资源的访问,而不需要运行进程意识到这些限制。有关linux命名空间的更多信息,请参见Linux命名空间;
防止容器内权限升级攻击的最佳方法是将容器的应用程序配置为以非特权用户的身份运行。对于进程必须以root
容器中的用户,您可以在Docker主机上将该用户重新映射到特权较低的用户。映射的用户被分配了一个UID范围,这些UID在命名空间中作为普通UID在0到65536之间运行,但是在主机本身上没有特权。
关于重映射和从属用户和组ID
重映射本身由两个文件处理:/etc/subuid
和/etc/subgid
每个文件的工作方式相同,但一个文件涉及用户ID范围,另一个文件涉及组ID范围。中的下列条目/etc/subuid
*
testuser:231072:65536
这意味着testuser
的从属用户ID范围为230172
接下来的65536个整数按顺序排列。UID231072
映射到容器内的命名空间%28中,在本例中%29映射为UID。0
%28root
29%。UID231073
映射为1
等等。如果某个进程试图在命名空间之外提升权限,则该进程在主机上作为一个非特权的高数字uid运行,它甚至不映射到真正的用户。这意味着进程在主机系统上完全没有特权。
多重范围 属性中的同一用户或组添加多个非重叠映射,从而为给定用户或组分配多个从属范围。
/etc/subuid
或/etc/subgid
档案。在这种情况下,Docker只使用六映射,这与内核仅限制在/proc/self/uid_map
和/proc/self/gid_map
...
当您将Docker配置为使用userns-remap
特性,您可以选择指定现有用户和/或组,也可以指定default
.如果您指定default
,用户和组dockremap
被创建并用于此目的。
警告某些发行版(如rhl和CentOS 7.3)不会自动将新组添加到
/etc/subuid
和/etc/subgid
档案。在本例中,您负责编辑这些文件并分配不重叠的范围。此步骤将在先决条件...
非常重要的是,范围不能重叠,这样进程就不能在不同的命名空间中获得访问权限。在大多数Linux发行版上,系统实用程序在添加或删除用户时为您管理范围。
这种重新映射对容器是透明的,但是在容器需要访问Docker主机上的资源的情况下,例如绑定安装到系统用户无法写入的文件系统的区域时,会引入一些配置复杂性。从安全的角度来看,最好避免这些情况。
先决条件
- 从属UID和GID范围必须与现有用户相关联,即使关联是实现细节。用户将拥有下面的命名空间存储目录。
/var/lib/docker/
如果您不想使用现有用户,Docker可以为您创建一个用户并使用它。如果要使用现有的用户名或用户ID,则必须已经存在。通常,这意味着相关条目需要在/etc/password
和/etc/group
但是,如果您使用的是不同的身份验证后端,则此要求可能会有不同的转换。 若要验证这一点,请使用id
指挥: $id testuser uid=1001%28 testuser%29 gid=1001%28 testuser%29组=1001%28 testuser%29
- 主机上处理名称空间重映射的方式是使用两个文件,
/etc/subuid
和/etc/subgid
这些文件通常在添加或删除用户或组时自动管理,但在少数发行版(如RHEL和CentOS 7.3)上,可能需要手动管理这些文件。
每个文件包含三个字段:用户的用户名或ID,后面是起始UID或GID%28,在命名空间%29中被视为UID或GID 0,以及用户可用的UID或GID的最大值。例如,考虑到以下条目:
测试用户:231072:65536
这意味着由testuser
将由主机UID拥有。231072
%28,它看起来像UID0
在命名空间%29到296608%28231072+65536%29中。这些范围不应重叠,以确保命名空间进程不能访问对方的命名空间。
添加用户后,请检查/etc/subuid
和/etc/subgid
若要查看用户在每个项目中是否有一个条目,请执行以下操作。如果不是,您需要添加它,小心避免重叠。
如果您想使用dockremap
由Docker自动创建的用户,您需要检查dockremap
这些文件中的条目后配置和重新启动Docker。
- 如果Docker主机上有任何位置需要非特权用户写入,则相应地调整这些位置的权限。如果要使用
dockremap
由Docker自动创建的用户,但在配置和重新启动Docker之前,您将无法修改权限。
- 使能
userns-remap
将有效地屏蔽现有图像和容器层,以及内部的其他Docker对象。/var/lib/docker/
这是因为Docker需要调整这些资源的所有权,并将它们实际存储在/var/lib/docker/
最好是在新的Docker安装上启用此功能,而不是在现有的安装上启用此功能。
如果您禁用userns-remap
您将不会看到在启用时创建的任何资源。
- 检查局限性在用户名称空间上,以确保您的用例是可能的。启用userns-在守护进程上重新映射你可以开始
dockerd
带着--userns-remap
标记或按照此过程使用daemon.json
配置文件。大daemon.json
推荐方法。如果使用此标志,请使用以下命令作为模型:$ dockerd --userns-remap="testuser:testuser"
- 编辑
/etc/docker/daemon.json
假设文件以前是空的,下面的条目将启用userns-remap
使用用户和组调用testuser
.您可以按ID或名称对用户和组进行寻址。如果组名或ID与用户名或ID不同,则只需要指定它。如果同时提供用户名和组名或ID,请用冒号%28分隔它们:
%29字符。假设UID和GID为testuser
是1001
*
- `testuser`
- `testuser:testuser`
- `1001`
- `1001:1001`
- `testuser:1001`
- `1001:testuser`
{“userns-remap”:“testuser”}
注*使用dockremap
用户和让Docker为您创建它,将值设置为default
而不是testuser
...
保存文件并重新启动Docker。
- 如果您使用的是
dockremap
用户,验证Docker使用id
命令。 $id dockremap uid=112%28 dockremap%29 gid=116%28 dockremap%29组=116%28 dockremap%29 验证条目是否已添加到/etc/subuid
和/etc/subgid
* $grep dockremap/etc/subuid dockremap:296608:65536$grep dockremap/etc/subgid dockremap:296608:65536 如果这些条目不存在,请将文件编辑为root
用户并分配一个起始UID和GID,这是分配最多的UID加上偏移量%28在本例中,65536
29%。小心不要让范围内有任何重叠。
- 控件验证以前的图像不可用。
docker image ls
命令。输出应该是空的。
- 从
hello-world
图像。 $docker运行Hello-world
- 验证名称空间目录是否存在于
/var/lib/docker/
命名为名称空间用户的UID和GID,由该UID和GID拥有,而不是组或世界可读的。一些子目录仍然属于root
并拥有不同的权限。
$sudo ls-ld/var/lib/docker/231072.231072/drwx。11 231072 231072 11 6月21日上午21:19/var/lib/docker/231072.231072/$sudo ls-l/var/lib/docker/231072.231072/共计14 drwx。5 231072 231072 5 6月21日6月21日上午21:19。3 231072 231072 3 6月21日上午21:21集装箱。3根根3 6月21日21:19图像drwxr-x-3根根3 6月21日21:19网络drwx。4根根4 6月21日21:19插件drwx。2根根2,6月21日上午21:19。2 231072 231072 2 6月21日上午21:21。2根根2 6月21日21:19信任drwx。2 231072 231072 3 6月21日21:19卷
您的目录清单可能有一些不同,特别是如果您使用的容器存储驱动程序与aufs
...
由重新映射的用户拥有的目录将被使用,而不是直接位于下面的相同目录。/var/lib/docker/
和未使用的版本%28,如/var/lib/docker/tmp/
在这里的示例中,%29可以删除。码头工人不会在userns-remap
已经启用。
禁用容器的命名空间重映射
如果在守护进程上启用用户名称空间,默认情况下,所有容器都是以启用的用户命名空间启动的。在某些情况下,例如特权容器,您可能需要禁用特定容器的用户命名空间。见用户命名空间已知限制其中一些限制。
若要禁用特定容器的用户命名空间,请添加--userns=host
标志到docker create
,,,docker run
,或docker exec
命令。
用户命名空间已知限制
以下标准Docker功能与启用用户命名空间的Docker守护进程不兼容:
- 与主机%28共享PID或网络命名空间
--pid=host
或--network=host
29%。
- 阿
--read-only
容器文件系统。这是Linux内核的限制,禁止在用户命名空间内重新安装带有修改标志的已安装的文件系统。
- 外部%28卷或存储%29驱动程序,这些驱动程序不知道或无法使用守护进程用户映射。
- 使用
--privileged
模式标志打开docker run
也没有指定--userns=host
...
用户名称空间是一种高级特性,需要与其他功能进行协调。例如,如果从主机挂载卷,则必须预先安排文件所有权,需要对卷内容进行读或写访问。
虽然用户命名空间容器进程中的根用户拥有容器内超级用户的许多预期权限,但Linux内核基于内部知识施加限制,即这是一个用户命名空间进程。一个值得注意的限制是无法使用mknod
命令。对象运行时,将拒绝在容器内创建设备的权限。root
用户。
© 2017 Docker, Inc.
根据ApacheLicense,版本2.0获得许可。
Docker和Docker标志是Docker公司在美国和/或其他国家的商标或注册商标。
Docker,Inc.和其他各方也可以在这里使用的其他术语中拥有商标权。
本文档系腾讯云开发者社区成员共同维护,如有问题请联系 cloudcommunity@tencent.com