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/*

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

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

主要的内核子系统不是命名空间的,例如

  • 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/priv 进程,原因与你在主机系统上运行它的原因完全相同。为了允许它访问非特权进程不可用的系统服务。本文的基本思想是以相同的方式对待这些进程。在下一篇文章中,我将介绍我们正在做些什么来使 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本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.