阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Docker 映像不安全

113次阅读
没有评论

共计 3312 个字符,预计需要花费 9 分钟才能阅读完成。

最近用 Docker 在下载一个官方镜像容器时我看到了这一行:

Ubuntu:14.04: The image you are pulling has been verified

我以为这引用了 Docker 大力推广的镜像签名系统,当时并没有深究。不久之后,在研究 Docker 用以加密镜像的加密摘要系统时,有了继续研究的机会。我发现镜像安全相关的所有逻辑完全系统性的失效。

Docker 的报告称一个下载的镜像仅仅以一个签过名的清单为验证基础, 并且 Docker 从不校验清单上的镜像的总和校验码。攻击者可以提供任意带有签名清单的镜像。这为一系列严重的漏洞埋下了隐患。

镜像通过一个 Docker 守护进程里无安全的流处理管道从一个 HTTPS 服务器上下载

[decompress] -> [tarsum] -> [unpack]

这个管道高效但不安全。非置信的输入不应在校验签名之前处理。不幸的是 Docker 在总和校验码验证之前要处理镜像三次。

不管 Docker 的声明 如何,镜像总和校验码从来没有实际校验过。这只是 Docker 校验镜像总和校验码相关的代码的 section0,在呈现一个有错误总和校验码的镜像时我甚至无法打开警告触发器。

if img.Checksum != “” && img.Checksum != checksum {
  log.Warnf(“image layer checksum mismatch: computed %q,
            expected %q”, checksum, img.Checksum)
}

不安全的处理管道

解压

Docker 支持三种压缩算法:gzip、bzip2 和 xz。前两个使用的是 Go 的标准库,它们是内存安全的,所以这里我想讨论的利用类型是拒绝服务攻击,比如崩溃、过多的 CPU 和内存使用。

第三个压缩算法 xz 更加有趣。因为没有原生的 Go 实现,所以 Docker 执行 thexzbinary 来解压缩。

Thexzbinary 来自于 XZ Utils 项目,构建自大约 20000 行的 C 代码。C 并不是一个内存安全的语言。这意味着存在向 C 程序恶意输入的可能,这样的话 Docker 镜像 XZ Utils 就被开箱了,可能会执行任意代码。

通过以管理员权限运行 xz,Docker 加剧了这个情况的发生。意味着只要在 xz 中存在一个漏洞,一个 docker pull 的调用就将导致整个系统的沦陷。

Tarsum

tarsum 的使用原本是善意的但却完全错了。为得到一个编码任意的 tar 文件的真实校验和,Docker 对 tar 解压然后取特定部分的哈希,以一个特定序列却不包含剩余部分。

由于这个处理是为了生成校验和,它解压了设计用来生成 tarsum 码 2 非可信数据。这里会有 DOS 和逻辑缺陷攻击的风险,可能导致文件被注入,跳过,差异化地处理,修改,添加等等。而校验和不会变化。

解压

解压包括解压 tar 并将文件放置到磁盘上。这也是非常危险,在写本文时已有三个其他的解压阶段的漏洞报告 2。

当文件还没被校验就解压到磁盘上时还没有解决措施。

libtrust

libtrust 是 Docker 的一个包,宣称提供“通过一个分布式的信任图来控制认证和访问。”但不幸的是不存在详细说明书,但它看起来像是实现了 Javascript Object Signing and Encryption 说明的一部分和其他未指明的算法。

下载一个使用 libtrust 签名和认证清单的镜像,会触发这个不安全的信息(仅仅检查了清单,而不是真实的镜像内容):

ubuntu:14.04: The image you are pulling has been verified

目前只有 Docker,Inc 发布的“官方”镜像使用这个系统签名,但从我最近参加的 Docker Governance Advisory Board 会议看,我的理解是 Docker,Inc 打算将来更广泛的部署这个系统。计划的目标是由 Docker,Inc 集中控制证书的认证,然后在镜像和 / 或客户端的证书上签名。

我在 Docker 的代码里找签名钥匙,但没能找到。结果证明这个钥匙并不像期望那样嵌入到了二进制程序中。相反,Docker 后台程序在各个镜像下载前,使用 HTTPS 从 CDN 上获取。这个方法很糟糕,因为很多攻击可以导致信任的钥匙被恶意的替换。这些攻击包括但不限于:CDN 主的妥协,CDN 原有托管钥匙的妥协,以及客户端的中间人攻击来下载钥匙。

修补措施

在我完成本次研究前,我报告了我发现的 tarsum 系统的一些问题,但目前为止我还没发现它们被修复。我认为以下措施有助于提高 Docker 镜像下载系统的安全:

丢弃 tarsum,真实验证镜像摘要

Tarsum 不应该用于安全。相反,镜像必须被完整下载,它们的私密签名要在进一步处理发生前进行验证。

添加权限隔离

镜像的处理步骤,包括解压或展开,应该在隔离的仅有最少必要操作权限的进程(容器?)中运行。没有像 xz 这样的解压工具在 root 下运行的场景。

替换 libtrust

libtrust 应该被 The Update Framework 替代,它被设计出来明显就是为了解决软件二进制签名的问题。威胁模型非常好理解,也强调了许多在 libtrust 里面没有考虑到的事。它有完整的说明书,也有一个 Python 的参考实现,我已经开始用 Go 实现,欢迎对其贡献。

作为添加 TUF 到 Docker 中的一部分,应该添加一个本地 key 仓库,用来将 root 钥匙映射到注册的 URL 上,这样用户就可以有自己的签名钥匙,而不是被 Docker,Inc 管理。

我想强调的是,使用非 Docker,Inc 托管的登记一般来说是非常差的用户体验。Docker,Inc 看起来把第三方登记降为第二等级的状态很满意,而并没有这样做的技术原因。这对于常见的生态系统和终端用户的安全都是一个问题。一个广泛的、去中心化的安全模型对与第三方登记来说,既是必要的也是值得的。我建议 Docker,Inc 在重新设计他们的安全模型和镜像认证系统时考虑下这个问题。

结论

Docker 用户要意识到下载镜像是非常不安全的。要只下载那些源没有问题的镜像。当前,这个问题没有影响到 docker 提供的信任的镜像,包括官方的 Ubuntu 镜像和其他的基本镜像。

最好的选择是本地屏蔽掉‘index.docker.io’,并且在使用‘docker load’导入到 docker 之前,先手动下载、验证一下镜像文件。Red Hat 的安全论坛上有很多好的相关的帖子(https://securityblog.RedHat.com/2014/12/18/before-you-initiate-a-docker-pull/)。

感谢 Lewis Marshall 指出了 tarsums 一直没有验证的问题。

CentOS 6/ 7 系列安装 Docker http://www.linuxidc.com/Linux/2014-07/104768.htm

Docker 的搭建 Gitlab CI 全过程详解 http://www.linuxidc.com/Linux/2013-12/93537.htm

Docker 安装应用 (CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

在 Docker 中使用 MySQL http://www.linuxidc.com/Linux/2014-01/95354.htm

在 Ubuntu Trusty 14.04 (LTS) (64-bit) 安装 Docker http://www.linuxidc.com/Linux/2014-10/108184.htm

Docker 安装应用 (CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Ubuntu 14.04 安装 Docker  http://www.linuxidc.com/linux/2014-08/105656.htm

阿里云 CentOS 6.5 模板上安装 Docker http://www.linuxidc.com/Linux/2014-11/109107.htm

Docker 的详细介绍 :请点这里
Docker 的下载地址 :请点这里

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-20发表,共计3312字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中