docker 图像在图像扫描中通常有超过 900 个漏洞吗?
Is it typical for a docker image to have over 900 vulnerabilities in an image scan?
我 运行 ruby debian docker 图像通过 gitlab 容器扫描,它返回了一个包含 900 多个 CVE 的列表,其中很大一部分可以追溯到 2016 年和 2017 年.这是官方rubydocker图片的清新版。所有 CVE 都被列为来自 debian 9 映像。这是容器扫描的典型结果吗,我真的可以做些什么吗?我原以为 debian 映像会保持最新和安全。
提取的确切图像是 ruby:2.5.1
来自 dockerhub
根据我的经验,这实际上很典型,我看到了发生这种情况的两个原因。
首先是,特别是对于可以具有 C 扩展的语言解释器,有时,预先打包的映像包含完整的 C 构建工具链。其中包括 Linux 个内核头文件。因为你有 Linux 个内核头文件,你会从安全扫描器发出响亮的警报,表明你有一个过时的内核,即使 Docker 本身没有 运行内核。
第二个有点可怕。如果您查看 https://hub.docker.com/_/ruby,您会看到现在有一个 MRI 2.5.5 图像,而不是那里列出的 2.5.1 图像。一般的做法似乎是为每个次要版本构建一个映像版本,但是一旦发布新的补丁版本,就停止发布旧补丁版本的更新。也就是说,您的 2.5.1 映像可能确实存在一些安全问题,并且永远不会有更新的官方映像来修复这些问题。
我发现的最佳解决方案是构建我自己的语言解释器基础映像,从您选择的 Linux 发行版开始,并定期自行重建它。然后它就在你的控制之下,你一定会在发布时获得安全更新。
The exact image pulled was ruby:2.5.1
from dockerhub
正如 David 提到的那样,当下一个补丁发布时,您将不再看到一个补丁的构建。在幕后,如果您配置 docker hub 为您构建,您将看到 docker 取决于 github 存储库上的标签,以及当您标记代码时,构建是由此触发的。您可以阅读有关他们 automated builds here 的更多信息。因此,除非您重新推送旧标签,否则它不会自动更新。在这种情况下,2.5.1 标签最后一次推送是在 6 个月前,并且已经有多个 2.5.x 版本取代了它。
您可以克隆 ruby repo 并根据自己的计划执行自己的构建。通过拉取新的基础镜像,可以使您的镜像保持最新。
您还可以使用基于 Alpine 的 ruby 图像,它的基础图像要小得多。减小的尺寸意味着可能易受攻击的预装应用程序更少。然而,这带来了一些可用性挑战,例如 musl 而不是 libc,并且其他一些预安装的应用程序可能很有用。
最简单的答案是,当您拥有基于 semver 的版本号时,不要使用特定的补丁版本。因此,您可以拉取 ruby:2.5
而不是 ruby:2.5.1
,当 2.5.2 发布时,它会为您的下一次拉取更新 2.5 标签。甚至还有一个简单的 ruby:2
图像可以自动将您更新到当前的 2.6 版本,而不会在发生这种情况时推送 3.x 版本的重大更改。
最后,如果您喜欢基于 Debian 的安装而不是 Alpine 版本,您仍然可以切换到带有精简映像的最小化版本的 Debian。在这种情况下,有一个 ruby:2.5-slim
会更小,同时仍保持最新 2.5 版本的更新。
我 运行 ruby debian docker 图像通过 gitlab 容器扫描,它返回了一个包含 900 多个 CVE 的列表,其中很大一部分可以追溯到 2016 年和 2017 年.这是官方rubydocker图片的清新版。所有 CVE 都被列为来自 debian 9 映像。这是容器扫描的典型结果吗,我真的可以做些什么吗?我原以为 debian 映像会保持最新和安全。
提取的确切图像是 ruby:2.5.1
来自 dockerhub
根据我的经验,这实际上很典型,我看到了发生这种情况的两个原因。
首先是,特别是对于可以具有 C 扩展的语言解释器,有时,预先打包的映像包含完整的 C 构建工具链。其中包括 Linux 个内核头文件。因为你有 Linux 个内核头文件,你会从安全扫描器发出响亮的警报,表明你有一个过时的内核,即使 Docker 本身没有 运行内核。
第二个有点可怕。如果您查看 https://hub.docker.com/_/ruby,您会看到现在有一个 MRI 2.5.5 图像,而不是那里列出的 2.5.1 图像。一般的做法似乎是为每个次要版本构建一个映像版本,但是一旦发布新的补丁版本,就停止发布旧补丁版本的更新。也就是说,您的 2.5.1 映像可能确实存在一些安全问题,并且永远不会有更新的官方映像来修复这些问题。
我发现的最佳解决方案是构建我自己的语言解释器基础映像,从您选择的 Linux 发行版开始,并定期自行重建它。然后它就在你的控制之下,你一定会在发布时获得安全更新。
The exact image pulled was
ruby:2.5.1
from dockerhub
正如 David 提到的那样,当下一个补丁发布时,您将不再看到一个补丁的构建。在幕后,如果您配置 docker hub 为您构建,您将看到 docker 取决于 github 存储库上的标签,以及当您标记代码时,构建是由此触发的。您可以阅读有关他们 automated builds here 的更多信息。因此,除非您重新推送旧标签,否则它不会自动更新。在这种情况下,2.5.1 标签最后一次推送是在 6 个月前,并且已经有多个 2.5.x 版本取代了它。
您可以克隆 ruby repo 并根据自己的计划执行自己的构建。通过拉取新的基础镜像,可以使您的镜像保持最新。
您还可以使用基于 Alpine 的 ruby 图像,它的基础图像要小得多。减小的尺寸意味着可能易受攻击的预装应用程序更少。然而,这带来了一些可用性挑战,例如 musl 而不是 libc,并且其他一些预安装的应用程序可能很有用。
最简单的答案是,当您拥有基于 semver 的版本号时,不要使用特定的补丁版本。因此,您可以拉取 ruby:2.5
而不是 ruby:2.5.1
,当 2.5.2 发布时,它会为您的下一次拉取更新 2.5 标签。甚至还有一个简单的 ruby:2
图像可以自动将您更新到当前的 2.6 版本,而不会在发生这种情况时推送 3.x 版本的重大更改。
最后,如果您喜欢基于 Debian 的安装而不是 Alpine 版本,您仍然可以切换到带有精简映像的最小化版本的 Debian。在这种情况下,有一个 ruby:2.5-slim
会更小,同时仍保持最新 2.5 版本的更新。