Docker 容器真的安全吗?

还没有读者喜欢这个。
Is Occupy Wall St. really an "open source protest?"

Opensource.com

本文基于我今年在 DockerCon 上做的 演讲,演讲题目是 Docker 安全(原名 Docker 和 SELinux)。本文将讨论 Docker 容器的安全性,我们目前的状况以及未来的发展方向。

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

容器并不包含一切

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

  • 我曾听人说 Docker 容器与在独立的虚拟机/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 启用?

© . All rights reserved.