lxd podman_Podman和用户名称空间:天堂里的婚姻

lxd podman

Podmanlibpod库的一部分,使用户可以管理Pod,容器和容器映像。 在上一篇文章中,我写了关于Podman的更安全的运行容器方法 。 在这里,我将解释如何使用Podman在单独的用户名称空间中运行容器。

我一直认为,主要由Red Hat的Eric Biederman开发的用户名称空间是分离容器的重要功能。 用户名称空间允许您指定用户标识符(UID)和组标识符(GID)映射以运行容器。 这意味着您可以在容器内部以UID 0运行,在容器外部以UID 100000运行。 如果您的容器进程对容器进行了转义,内核会将其视为UID100000。不仅如此,UID所拥有但未映射到用户名称空间的任何文件对象都将被视为“ nobody”所拥有(65534, kernel.overflowuid),除非该对象可被“其他”(世界可读写)访问,否则将不允许容器进程访问。

如果您拥有“真实”根目录并具有权限660的文件 ,并且用户命名空间中的容器进程尝试读取该文件,则将阻止它们访问该文件,并将该文件视为没有人拥有。

一个例子

这可能是这样的。 首先,我在系统中由root拥有一个文件。


   
   
$ sudo bash -c "echo Test > /tmp/test"
$ sudo chmod 600 /tmp/test
$ sudo ls -l /tmp/test
-rw-------. 1 root root 5 Dec 17 16:40 /tmp/test

接下来,我将文件批量安装到运行有用户名称空间映射0:100000:5000的容器中。


   
   
$ sudo podman run -ti -v /tmp/test:/tmp/test:Z --uidmap 0:100000:5000 fedora sh
# id
uid=0(root) gid=0(root) groups=0(root)
# ls -l /tmp/test
-rw-rw----. 1 nobody nobody 8 Nov 30 12:40 /tmp/test
# cat /tmp/test
cat: /tmp/test: Permission denied

上面的--uidmap设置告诉Podman将容器内部的5000个UID范围映射到容器外部的UID 100000(因此范围为100000-104999)到容器内部的UID 0开始的范围(因此范围为0-4999)。 在容器内,如果我的进程以UID 1运行,则在主机上为100001

由于实际UID = 0没有映射到容器中,因此root拥有的任何文件都将被视为没人拥有。 即使容器内的进程具有CAP_DAC_OVERRIDE ,它也不能覆盖此保护。 DAC_OVERRIDE使根进程能够读/写系统上的任何文件,即使该进程不是由root拥有也不是世界可读或可写的。

用户名称空间功能与主机上的功能不同。 它们是命名空间功能。 这意味着我的容器根仅在容器内具有功能,实际上仅在映射到用户名称空间的UID范围内。 如果容器进程逃避了该容器,则它将对未映射到用户名称空间的UID(包括UID = 0)没有任何功能。 即使进程可以以某种方式进入另一个容器,但是如果容器使用不同范围的UID,它们将不会具有这些功能。

请注意,SELinux和其他技术也限制了如果容器进程脱离容器会发生的情况。

使用`podman top`显示用户名称空间

我们在podman top中添加了功能,使您可以检查容器中运行的进程的用户名并在主机上标识它们的实际UID。

让我们从使用我们的UID映射运行一个睡眠容器开始。

 $ sudo podman run --uidmap 0:100000:5000 -d fedora sleep 1000 

现在运行podman top


   
   
$ sudo podman top --latest user huser
USER   HUSER
root   100000

$ ps -ef | grep sleep
100000   21821 21809  0 08:04 ?         00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000

注意podman top报告用户进程正在容器内以root用户身份运行,但在主机(HUSER)上以UID 100000运行。 ps命令还确认睡眠进程正在作为UID 100000运行。

现在,我们运行另一个容器,但是这次我们将选择一个从200000开始的单独的UID映射。


   
   
$ sudo podman run --uidmap 0:200000:5000 -d fedora sleep 1000
$ sudo podman top --latest user huser
USER   HUSER
root   200000

$ ps -ef | grep sleep
100000   21821 21809  0 08:04 ?         00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000
200000   23644 23632  1 08:08 ?         00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1000

请注意, podman top报告第二个容器在该容器内以root用户身份运行,但在主机上以UID = 200000身份运行。

还要查看ps命令-它显示两个睡眠进程都在运行:一个为100000,另一个为200000。

这意味着在单独的用户名称空间中运行容器可为您提供进程之间的传统UID分隔,这从一开始就是Linux / Unix的标准安全工具。

用户名称空间问题

几年来,我一直提倡用户名称空间作为每个人都想要但几乎没有人使用过的安全工具。 原因是没有任何文件系统支持或文件系统转移。

在容器中,您要在许多容器之间共享基本映像。 上面的示例在每个示例中都使用Fedora基本映像。 Fedora映像中的大多数文件由实际UID = 0拥有。 如果我在此图像上使用用户名称空间0:100000:5000运行容器,默认情况下,它将所有这些文件视为没有人拥有,因此我们需要移动所有这些UID来匹配用户名称空间。 多年来,我一直希望使用挂载选项来告诉内核重新映射这些文件UID以匹配用户名称空间。 上游内核存储开发人员继续研究此功能并取得进展,但这是一个难题。

chowning建成集装箱/存储由纳林Dahyabhai领导的一个小组。 Podman使用容器/存储,并且Podman首次在新的用户命名空间中使用容器映像,容器/存储将图像中的所有文件“ chowns”(即更改所有权)到用户命名空间中映射的UID并创建一个新图片。 将其视为fedora:0:100000:5000图像。

当Podman在具有相同UID映射的图像上运行另一个容器时,它将使用“预先拥有”的图像。 当我在0:200000:5000上运行第二个容器时,containers / storage创建了第二个映像,我们将其称为fedora:0:20​​0000:5000

请注意,如果您正在执行podman构建podman提交 ,并将新创建的映像推送到容器注册表,则Podman将使用容器/存储来反转移位,并将映像与所有文件一起推回真实UID = 0。

这可能会导致在新的UID映射中创建容器时确实变慢,因为chown可能会变慢,具体取决于映像中的文件数。 另外,在普通的OverlayFS上 ,图像中的每个文件都会被复制。 正常的Fedora图像最多可能需要30秒才能完成加弦并启动容器。

幸运的是,红帽内核存储团队(主要是Vivek Goyal和Miklos Szeredi)在内核4.19中为OverlayFS添加了新功能。 该功能称为仅元数据复制 。 如果使用metacopy = on作为安装选项来安装覆盖文件系统,则在更改文件属性时它不会复制较低层的内容; 内核会创建新的索引节点,这些索引节点包含带有指向较低级别数据的引用的属性。 如果内容更改,它将仍然复制内容。 如果您想试用一下,该功能在Red Hat Enterprise Linux 8 Beta中可用。

这意味着可以在几秒钟内完成容器的穿刺操作,而且每个容器的存储空间不会增加一倍。

这使得在单独的用户命名空间中使用Podman之类的工具运行容器变得可行,从而大大提高了系统的安全性。

向前走

我想向Podman添加一个新的标志,例如--userns = auto ,它将告诉它为您运行的每个容器自动选择一个唯一的用户命名空间。 这类似于SELinux与单独的多类别安全性(MCS)标签一起使用的方式。 如果设置环境变量PODMAN_USERNS = auto ,则甚至不需要设置标志。

Podman最终允许用户在单独的用户命名空间中运行容器。 诸如BuildahCRI-O之类的工具也将能够利用用户名称空间。 但是,对于CRI-O,Kubernetes需要了解哪个用户名称空间将运行容器引擎,并且上游正在对此进行工作。

在我的下一篇文章中,我将解释如何在用户名称空间中以非root用户身份运行Podman。

翻译自: https://opensource.com/article/18/12/podman-and-user-namespaces

lxd podman

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值