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