受启发于在生产环境中运行Docker时应考虑的最佳和全面实践是什么? ,我偶然发现了为什么我们不让非root用户运行Docker ...

他们想出了docker run -ti --privileged -v /:/host fedora chroot /host,这将您的非特权用户(但docker分组)放置在了主机(不在容器中)。

无需提及,这对于生产系统来说是个坏消息。

如何避免这种情况或类似的事情?我假设docker守护程序无法以非root用户身份运行(否则可能是启动它的默认方式)?我想到的一种解决方案不是将非特权用户置于docker组中,而仅允许通过sudoers使用特定的docker命令行。但这足够了吗?

如果映像照常运行(即root),我们是否知道突破容器并获得主机docker run --rm -it myimage的外壳(如给定示例)有多难?我什至没有在谈论通过容器中运行的服务进行的攻击,而是通过专门准备的映像来进行。

编辑:为澄清起见,我对此攻击场景特别感兴趣: />

不受信任的软件开发人员可以提供易于运行的映像。
受信任的用户可以在生产系统上以常规方式(即docker --rm -it myimage)运行该映像,而无需--privileged。 />

子场景可能为-u unprivileged_u


创建映像的不受信任的人有合理的机会脱离docker吗容器运行时?也就是说,是否比经典的chroot或经典的权限提升高?

EDIT2:我的研究仅显示了一个真正的突围事件,该事件由Docker Engine 0.12修复,然后在1.0.1中修复。另外,我发现对此至关重要的所有内容都提到了docker守护进程的TCP / IP接口,该接口很长时间以来已更改为Unix套接字。还有别的吗,或者您说只要输入/运行实际的docker命令的人就可以了,就没问题吗?

评论

值得一读,而且总结起来太长了:blackhat.com/docs/eu-15/materials/…

有趣的读物,感谢您,@ Tensibai,但实际上没有什么新鲜的-总而言之,它表示控制docker命令可以打开主机上的根访问权限(但这不是此问题的确切含义),并且其中包含参考解决2015年以来的旧安全问题。

确实没有什么新东西,我确实认为它会给周围带来更多反馈。我还有另一个专门针对集装箱逃逸的人,但是我必须在共享之前检查日期和兴趣(并确保我也可以共享)

我肯定对任何事情都感兴趣-如果我对资源感到不满,那是因为它并没有特别解决这个问题。您的努力当然值得赞赏。 @Tensibai

你并没有听起来不高兴,我没有明确地说这只是和顺便说一句有关。没问题

#1 楼

与仅将用户添加到docker组相比,第二个链接解决方案不再安全。

请注意该页面如何仍可以使用--privileged标志启动,并且该页面在不受限制的情况下运行。 >
unconfined_u:unconfined_r:unconfined_t

这意味着容器可以访问所有资源,包括主机磁盘和硬件。这是通过隐秘实现的安全,而不是安全。任何知道如何使用mknod或遍历/ sys和/ proc树的人都可以轻松地以零日志记录来破坏主机和所有容器。

现实是docker改变了复杂性和安全性边界。在该安全上下文中,所有可以启动容器或访问API的用户都必须限制为受信任的用户。 />
命名空间不是安全功能,它依赖于apparmor和selinux来实施合理的约束。 docs.docker.com/engine/security/security/#control-groups

'首先,应仅允许受信任的用户控制您的Docker守护程序。'

docker / kube的安全功能不是像传统的unix权限那样的管理边界,它们是防止非特权容器破坏的工具。

在docker世界中,管理边界成为主机,并且在该上下文中隔离应用程序或用户所需的选择和细分需要在该边界处应用。

此方法的好处如果考虑到这些更改,实施复杂性和责任制方面的变化通常会大于风险。使用--privlaged标志==运行容器,以suid或root用户身份运行Web服务。OP的编辑中涉及的突破问题是非uid0特权升级。

不幸的是,由于仅需要执行root操作,Docker需要启用某些功能,以便apt / dnf可以安装软件包等。 ...

如果在此默认配置下运行生产工作负载,这一需求确实会带来风险,并且应该对生产工作负载采用最低特权的安全性原则。

--privileged禁用apparmor / selinux并打开功能

我正在使用ubuntu,但完成以下步骤可能会很有用。首先使用docker run -i --rm -t debian bash启动默认容器。从父主机使用ps查找bash的PID,并注意该进程是root用户。如果查看--privileged,您将看到它运行的上下文。 capability.h以获得更好的信息,但是夏天是

CapInh =继承的功能(由docker提供的功能)
CapPrm =由于权限(在容器OS内)而导致的功能
=有效功能

您可以通过运行以下命令将其解码为人类可读的形式:

# egrep '^Cap(Prm|Inh|Eff)' /proc/16026/status
 CapInh:    00000000a80425fb
 CapPrm:    00000000a80425fb
 CapEff:    00000000a80425fb


现在对/proc/$PID/status进行相同的操作,您会发现有效的功能是$ docker run -i --rm --privileged -t debian bash

也只需在两个VM中都执行0000003fffffffff,您就会看到特权容器具有多少访问权限。或SElinux中的标签,您将看到含义。

作为示例,您可以通过放下所有大写字母来运行它,以对其进行测试。通过上面的dir /dev方法进行了验证。

$ capsh --decode=00000000a80425fb


请注意,它们全部为零,来自CapInh。然后,如果必须启用该应用程序的功能,则可以在/etc/apparmor.d/docker后使用/proc/$PID/status,例如,--cap-add将破坏ping:我们可以添加--cap-drop=all上限。 Docker期望删除带有--cap-drop=all前缀的参数,因此命令为cap_net_raw
将允许容器从父主机添加或删除内核模块。

cap_sys_rawio将打开内存,所有要攻击的块设备

cap_sys_admin非常危险。

因此在这种情况下,我将查看您是否可以在此上下文中运行事物。

$ docker run -i --rm -t --cap-drop = all -u none: nogroup -t debian bash

希望随着时间的流逝,apparmor和selinux配置文件的健壮性会提高,但是如果这不足以满足您的安全需求,也可以在其中查看。确实,避免使用--privileged标志并使用最小特权原则将产生最大的影响。特别是如果您利用容器的短暂特性来使软件包保持最新。

如果您需要更多的内容,则Red Hat在此处介绍了一些基本的seccomp选项。

https:/ /access.redhat.com/documentation/zh-CN/red_hat_enterprise_linux_atomic_host/7/html/container_security_guide/linux_capabilities_and_seccomp

评论


谢谢您的详细答复,这对于明确界限当然有帮助。我认为,让不信任的用户访问docker守护进程是一个坏主意,如该链接文章所示。我在问题中添加了EDIT,以阐明我的前进方向。你可以在这上面加上几句话吗?

– AnoE
17年9月8日在7:42

与“突破”相关,该问题是非root用户可以获取root访问权限的问题。根仍然是根,由于注释中没有足够的空间,因此我将使用更多信息来编辑响应。

– gdahlm
17年9月9日在22:30