本文基于我今年在 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* 文件系统设备
- 内核模块
如果你可以作为特权进程与其中任何一个通信或攻击,你就可以控制系统。
8 条评论