当我以普通用户身份运行容器时,我可以在主机文件系统上映射并修改root所拥有的目录。这似乎是一个很大的安全漏洞。例如,我可以执行以下操作:
$ docker run -it --rm -v /bin:/tmp/a debian
root@14da9657acc7:/# cd /tmp/a
root@f2547c755c14:/tmp/a# mv df df.orig
root@f2547c755c14:/tmp/a# cp ls df
root@f2547c755c14:/tmp/a# exit
现在,我的主机文件系统将在输入ls
时执行df
命令(主要是无害的示例)。我无法相信这是理想的行为,但它发生在我的系统中(debian stretch)。 docker
命令具有正常权限(755,不是setuid)。
我错过了什么?
也许澄清一点是好的。我现在不对容器本身做什么或能做什么感兴趣,也不关心容器内的root访问权。
相反,我注意到我的系统上任何可以运行docker容器的人都可以使用它来获取对我的主机系统的root访问权限,并以root身份读取/写入它们:有效地为所有用户提供root权限访问。这显然不是我想要的。如何防止这种情况?
答案 0 :(得分:8)
有许多Docker安全功能可用于帮助解决Docker安全问题。对您有用的具体功能是用户名空间。
基本上你需要在主机上启用用户命名空间,事先停止Docker守护程序:
dockerd --userns-remap=default &
请注意,这将禁止容器以特权模式运行(从安全角度来看是件好事)并重新启动Docker守护程序(应在执行此命令之前将其停止)。进入Docker容器时,可以将其限制为当前的非特权用户:
docker run -it --rm -v /bin:/tmp/a --user UID:GID debian
无论如何,尝试使用默认的
命令进入Docker容器docker run -it --rm -v /bin:/tmp/a debian
如果您尝试操作映射到Docker卷(在本例中为/bin
)的主机文件系统,其中文件和目录归root所有,那么您将收到Permission denied
错误。这证明了用户名空间提供了您正在寻找的安全功能。
我建议您通过https://github.com/docker/labs/tree/master/security/userns上的此安全功能访问Docker实验室。我已经完成了所有的实验室,并在那里开设了问题和PR,以确保实验室的完整性并为其提供担保。
答案 1 :(得分:3)
在主机上访问运行docker命令是访问该主机上的root用户。这是该工具的设计,因为安装文件系统和隔离应用程序的功能需要linux上的root功能。此处的安全漏洞是任何系统管理员,它授予用户访问权限以运行docker命令的权限,否则他们不会信任该主机上的root访问权限。因此,应谨慎地将用户添加到docker组。
如果正确使用,我仍然认为Docker是一种安全性改进,因为在容器内运行的应用程序受限于他们对主机的操作。通过运行容器的明确选项给出了造成损害的能力,例如将根文件系统挂载为rw卷,直接访问设备或向root添加允许转义命名空间的功能。除非明确创建这些安全漏洞,否则在容器内运行的应用程序访问的次数远远少于在容器外部运行的应用程序。
如果您仍想尝试锁定可以访问docker的用户,还有一些其他安全功能。用户命名空间是阻止容器内的root用户在主机上具有root访问权限之一。还有interlock,它允许您限制每个用户可用的命令。
答案 2 :(得分:0)
您缺少默认情况下内部以uid 0运行的容器。所以这是预期的。如果要在容器内更多地限制权限,请在Dockerfile中使用USER
语句构建它。这将在运行时setuid给指定的用户,而不是以root身份运行。
请注意,此用户的uid不一定是可预测的,因为它是在您构建的图像内部分配的,并且它不一定映射到外部系统上的任何内容。但重点是,它不会成为root。
有关详细信息,请参阅Dockerfile reference。