不安全的镜像
开发者通常会在 Docker 官方的 Docker Hub 仓库下载镜像,这些镜像一部分来源于开发镜像内相应软件的官 方组织,但还有大量镜像来自第三方 组织甚至个人。在整个应用生命周期中,开发人员、测试人员和运维人员会 根据不同需求下载并运行镜像,所以在容器运行前进行镜像检查非常重要。除了 Docker Hub 外,还有大量的第三方镜像仓库,如国内的网易 163[42](需注册)、中国科学技术大学(USTC)[43] (公共开放)、daocloud[44](需注册)、阿里云 [45] 等。这些第三方镜像仓库,在提供方便获取镜像的同时,也 带来了潜在的安全风险 。例如,下载镜像内软件本身是否就包含漏洞,下载的镜像是否被恶意的植入后门,镜像 在传输过程中是否被篡改。(1)镜像使用包含漏洞的软件 有关研究报告 [46] 显示,Docker Hub 中超过 30% 的官方镜像包含高危漏洞,接近 70% 的镜像有着高危或中 危漏洞。本文从 Docker Hub 中选择评价和下载量较高的 10 个镜像,对其最新版 本(latest)采用 Clair[47]工具进 行了扫描分析,结果如表 3.1 所示。
| 镜像 | STARS | PULLS | HIGH | MEDIUM | LOW | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| nginx | 8.1K | 10M+ | 3 | 14 | 8 | |||||||
| ubuntu | 7.3K | 10M+ | 0 | 6 | 14 | |||||||
| mysql | 5.8K | 10M+ | 4 | 7 | 5 | |||||||
| node | 5.2K | 10M+ | 68 | 193 | 71 | |||||||
| redis | 4.9K | 10M+ | 6 | 11 | 9 | |||||||
| pos | ||||||||||||
| tgres | 4.7K | 10M+ | 15 | 32 | 12 | mongo | 4.2K | 10M+ | 6 | 11 | 9 | |
| centos | 4.1K | 10M+ | 0 | 0 | 0 | |||||||
| jenkins | 3.4K | 10M+ | 11 | 25 | 21 | |||||||
| alpin | ||||||||||||
| e | 3.3K | 10M+ | 0 | 0 | 0 | |||||||
| 从表中可以看出,绝大多数的镜像存在高危漏洞,有的镜像高危漏洞数量甚至达到数十个之多。漏洞镜像基 本都出现在应用软件,而主流操作系统的脆弱性管理较好,比如 centos 和 alpine 没有扫描出 CVE漏洞。 | ||||||||||||
| (2)攻击者上传恶意镜像 | ||||||||||||
| 如果有黑客在制作镜像时植入木马、后门等恶意软件,并将恶意镜像上传至 Docker Hub 等公共仓库,那么 用户的容器环境从一开始就已经不安全了,后续更没有什么安全可言。 | ||||||||||||
| 比如 Docker 对镜像不安全的处理管道,Docker 支持三种压缩算法,分别是 gzip、bzip2、xz。gzip 和 bzip2 使用 Go的标准库,所以相对安全;xz由于没有使用原生的 Go去实现,又由于其使用由 C编写的 XZ Utils开源项目, 所以存在 C 程序恶意写入的可能,一旦被写入会导致执行任意代码漏洞,而只要有一个漏洞,执行 docker pull 拉取镜像时就有可能导致整个系统沦陷。 |
对于特定某文件,一般可以使用杀毒软件进行扫描以确定该文件是否安全,但是目前的杀毒软件并没有能够 很好支持镜像的扫描。用户想确认下载的镜像是否安全,只能仔细检查下载的源是否有后门(比如运行镜像,然 后在里面安装杀毒软件扫描),并且确认我们的请求指向官方源。 (3)中间人攻击篡改镜像 如果用户采用非加密的方式从镜像仓库下载镜像,镜像在传输过程中可能被中间人篡改。Docker 在 v1.8 版 本中启用内容机制,其中已提供了相应的校验机制来应对这个问题。
容器隔离失效
由于容器与主机共享内核,可能会存在容器隔离失效的安全风险,主要有以下几种场景:
- 攻击者只要攻破容器操作系统内核,就可访问到主机上的文件系统,或进入其它容器,导致容器隔离失效。
- 主机的文件系统可以被挂载到多个容器的目录里,那么不同的容器就可以访问同一个目录。例如只要进 入某个容器中,就可以通过共同挂载目录,访问其它容器的文件系统,这样可能会引起信息泄露或内容 篡改等安全问题。
安全威胁分析
容器的安全威胁问题主要包括三点,分别是对主机的威胁,对容器的威胁和对承载应用造成的威胁。
容器逃逸攻击
容器逃逸攻击与虚拟机逃逸攻击相似,利用虚拟化软件存在的漏洞,通过容器获取主机权限入侵主机,以达 到攻击主机的目的。 具体地,一些 PoC 工具,如 Shocker[48],可展示如何从 Docker 容器逃逸并读取到主机某个目录的文件内容。 Shocker 攻击的关键是执行了系统调用 open_by_handle_at 函数,Linux 手册中特别提到调用 open_by_handle_at 函数需要具备 CAP_DAC_READ_SEARCH能力,而 Docker1.0 版本对 Capability 使用黑名单管理策略,并且没有 限制 CAP_DAC_READ_SEARCH能力,因而引发了容器逃逸的风险。
容器网络攻击
目前 Docker 总共提供三种不同的网络驱动,分别是桥接网络(Bridge Network),MacVLAN,覆盖网络(Overlay Network),三种网络驱动都存在着安全风险。 第一种是 Docker 预设的桥接网络驱动,一个 docker0 的网桥将所有容器连接该网桥,docker0 网桥扮演着 路由和 NAT的角色,容器间通信都会经过容器主机。如果各容器之间没有防火墙保护,攻击者就可以利用主机 内部网络进行容器间相互攻击。 第二种是 MacVLAN,这是一种轻量级网络虚拟化技术,MacVLAN与主机的网络接口连接,MacVLAN相比 于桥接网络驱动加强了与实体网络的隔离性,但是在该网络驱动中,同一个虚拟网络下的容器之间没有进行权限 管控,攻击者可以轻易获得容器权限并进行网络攻击。
对此 Docker 官方提供了一些扩展插件来实现对容器权限细粒度的控制,例如网络插件(Network Plugins) 可以提供容器间互联网络模型;数据卷插件(Volume Plugins)可以使 Docker 数据卷跨多个主机;验证插件 (Authorization Plugins)可以提供基于权限的访问控制等。 第三种是 Overlay Network,主要是利用 VXLAN技术,在不同主机之间的 Underlay 网络之上再组成新的虚 拟网络。这种网络架构在分布式的编排框架中常常用到,在快速构建分布式容器集群的同时,也存在着一些弊端。 最为明显的是 VXLAN网络上的流量没有加密,传输内容很容易被攻击者盗取或篡改。 不过 Docker 使用者可以在设定 IPsec Tunnel 参数时,选择加密来保证容器网络的安全。此外,与前两种驱 动一样,Overlay Network 模式下容器间的连接并未有效控制,这也是目前容器网络普遍存在的问题,可能会导 致如 ARP欺骗、嗅探、广播风暴等攻击。
拒绝服务攻击
由于容器在技术实现上基于主机内核,采用共享主机资源的方式,因此面向容器的拒绝服务攻击(DoS)威 胁程度更高。例如,默认情况下容器可以使用主机上的所有内存,如果某个容器以独占方式访问或消耗主机的大 量资源,则该主机上的其它容器就会因为缺乏资源而无法正常运行。 DoS 攻击可针对任何资源,例如计算资源、存储资源、网络资源等,下面分别以这三种资源进行说明。 (1)计算资源 Fork Bomb[^1] 是一个很典型的计算型 DoS 攻击场景,主机内核正常情况下只能支持一定数量的进程,如果某 个容器内的进程组新建过多进程,消耗了主机上的所有进程资源,那其它的容器就没有资源来创建新的进程,甚 至会危及主机的正常工作。 Fork Bomb 也是自 2015 年到现在 Docker 社区一直讨论的问题,目前最好的方法是限制内存的使用 (--kernel-memory=#M ),但是,当在与加密文件一起使用时可能会偶尔出现问题。 (2)存储资源 在容器技术的实现中,通过 mount 命名空间实现了文件系统的隔离。但是文件系统隔离仅仅是一个非常基 本的要求。不建议使用 AUFS做存储驱动,虽然 AUFS创建出的容器文件系统互相隔离,但是在存储空间方面却 没有任何限制。换言之,一个容器如果不断写文件,将会写满存储介质,其它容器将无法执行写操作,导致拒绝 服务攻击。 (3)网络资源 DoS 攻击层出不穷,容器内网络带宽耗尽也是其中一种,攻击者使用大量的受控主机向被攻击目标(容器) 发送大量的网络数据包,以占满容器的网络宽带,并消耗容器主机的网络数据处理能力,达到拒绝服务的目的。