Docker 容器真的安全吗?

尚无读者喜欢这篇文章。
Is Occupy Wall St. really an "open source protest?"

Opensource.com

本文基于我今年在 DockerCon 上所做的演讲。它将讨论 Docker 容器的安全性,我们目前的状况以及未来的发展方向。

这是关于 Docker 安全性系列文章的一部分,请阅读第二部分

容器并不包含

我听到和读到很多人认为 Docker 容器实际上可以沙箱化应用程序——这意味着他们可以使用 Docker 在其系统上以 root 身份运行随机应用程序。他们认为 Docker 容器实际上会保护他们的主机系统。

  • 我曾听人说 Docker 容器与在单独的 VM/KVM 中运行进程一样安全。
  • 我知道有人在下载随机的 Docker 镜像,然后在他们的主机上启动它们。
  • 我甚至见过 PaaS 服务器(尚不是 OpenShift)允许用户上传他们自己的镜像以在多租户系统上运行。
  • 我有一位同事说:“Docker 就是运行从互联网上下载的随机代码并以 root 身份运行它。”

“你愿意走进我的客厅吗?” 蜘蛛对苍蝇说

不要再假设 Docker 和 Linux 内核会保护你免受恶意软件的侵害。

你关心吗?

如果你不是在多租户系统上运行 Docker,并且你对容器内运行的服务使用了良好的安全实践,你可能不需要担心。只需假设在容器内运行的特权进程与在容器外运行的特权进程相同。

有些人犯了一个错误,认为容器是运行虚拟机的一种更好更快的方式。从安全角度来看,容器要弱得多,我将在本文后面介绍这一点。

如果你像我一样认为,Docker 容器应该被视为“容器服务”——意味着将运行 Apache 的容器视为与你在系统上运行 Apache 服务相同的方式,这意味着你应该执行以下操作

  • 尽可能快地放弃特权
  • 尽可能以非 root 用户身份运行你的服务
  • 将容器内的 root 视为与容器外的 root 相同

目前,我们正在告知 通用标准 中的人们,将容器内的特权进程与容器外运行的特权进程以相同的标准对待。

不要在你的系统上运行随机的 Docker 镜像。在很多方面,我将 Docker 容器革命视为类似于 1999 年左右的 Linux 革命。那时,当管理员听说一个新的很酷的 Linux 服务时,他们会

  • 在互联网上搜索软件包,例如 rpmfind.net 或随机网站
  • 将程序下载到他们的系统上
  • 通过 RPM 或 make install 安装它
  • 以特权身份运行它

可能出什么问题呢?

两周后,管理员听说了一个 zlib 漏洞,并且不得不弄清楚他们的软件是否易受攻击,同时希望并祈祷它不是!

这就是 Red Hat 发行版和其他一些可信方介入来拯救局面的时候。Red Hat Enterprise Linux 为管理员提供

  • 他们可以从中下载软件的可信仓库
  • 安全更新以修复漏洞
  • 安全响应团队,用于查找和管理漏洞
  • 一支工程师团队,用于管理/维护软件包并致力于安全增强
  • 通用标准认证,用于检查操作系统的安全性

仅运行来自可信方的容器。我相信你应该继续从你过去获取代码/软件包的同一批人那里获取。如果代码不是来自内部或可信的第三方,请不要依赖容器技术来保护你的主机。

那么问题是什么?为什么容器不具备隔离性?

最大的问题是 Linux 中的一切都不是命名空间化的。目前,Docker 使用五个命名空间来改变进程对系统的视图:进程、网络、挂载、主机名、共享内存。

虽然这些为用户提供了一定程度的安全性,但它远非像 KVM 那样全面。在 KVM 环境中,虚拟机中的进程不直接与主机内核对话。它们无权访问内核文件系统,如 /sys/sys/fs, /proc/*

设备节点用于与虚拟机的内核而不是主机对话。因此,为了从虚拟机中提升权限,进程必须颠覆虚拟机的内核,在 HyperVisor 中找到漏洞,突破 SELinux 控制(sVirt),这些控制在虚拟机上非常严格,最后攻击主机内核。

当你在容器中运行时,你已经到了与主机内核对话的地步。

主要的内核子系统没有命名空间化,例如

  • SELinux
  • Cgroups
  • /sys 下的文件系统
  • /proc/sys, /proc/sysrq-trigger, /proc/irq, /proc/bus

设备没有命名空间化

  • /dev/mem
  • /dev/sd* 文件系统设备
  • 内核模块

如果你可以作为特权进程与其中任何一个通信或攻击,你就可以控制系统。

User profile image.
Daniel Walsh 在计算机安全领域工作了近 30 年。Dan 于 2001 年 8 月加入 Red Hat。

8 条评论

所以基本上,如果你在其中运行一个非特权服务,且没有 root 访问权限,那么你的服务应该是被隔离的。我不明白为什么会有人允许容器中的进程以 root 身份运行,这有点违背了意义,对吧?

可悲的是,Docker 中的默认设置是以 root 身份运行所有内容。

你可以通过在 Dockerfile 中显式设置 USER 指令,或使用 “docker run -u <user>” 启动来降级到用户帐户,但你必须知道要显式地执行这些操作。目前,Docker 默认是不安全的。

回复 作者 Chris Done (未验证)

嗯,不完全是。你会在容器内运行 root/特权进程,原因与你在主机系统上运行特权进程的原因完全相同。为了允许它访问非特权进程无法访问的系统服务。本文的基本思想是以相同的方式对待这些进程。在下一篇文章中,我将介绍我们正在做些什么来使 Docker 更加安全。

Dan,

你能推荐一些关于 Linux 安全性的资料吗——书籍/网站/等等?

谢谢,
Jeff

你写道

""""
设备没有命名空间化

/dev/mem
/dev/sd* 文件系统设备
"""

然而,Docker 容器无权访问这些设备。Docker 对设备有一个非常短的白名单。https://github.com/docker/libcontainer/blob/master/devices/defaults.go

非 root 这件事有点转移注意力,不是吗?它是基于这样一种想法,即人们无法在容器内获得 root 权限,这直接回到了容器卫生以及清理导入软件的复杂性。

如果只有在不可能获得 root 权限的情况下容器才是安全的,那为什么还要使用容器?直接使用非 root 用户即可。

rob2:取决于你使用容器的目的。

例如,Docker 为你提供了一个命名空间化的文件系统。因此,你可以捆绑你自己的依赖项,独立于主机操作系统。网络也是如此。这使得控制你的应用程序运行的环境变得容易得多。

Docker 是一个很好的分发平台,但它不是一个安全平台。

回复 作者 rob2 (未验证)

嗨,Daniel,

好文章!

你能提供更多关于库和二进制文件如何与其他容器和内核共享的细节吗?这是一个安全问题吗?你不能共享库和二进制文件吗?这是否仅通过 AUFS 和 Device Mapper 启用?

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.