随着企业为云原生应用程序采用容器、微服务和 Kubernete,漏洞管理对于在构建、部署和运行期间改善容器化工作负载的安全态势至关重要。
保护构建工件和部署管道,尤其是在涉及到镜像时,是极其重要的。
在整个应用程序开发和部署过程中遵循镜像构建和扫描的最佳做法,可以帮助确保环境中容器和工作负载的安全。
让我们看看选择基础镜像、增强容器镜像和容器镜像扫描,包括选择适当扫描解决方案和解决隐私问题的提示。
选择适当的基础镜像
选择一个能够减少容器攻击面的基础镜像很重要。笔者建议使用 distroless 或 scratch 镜像,因为它们只包含应用程序及其运行时依赖关系。这两种类型的图像通过减少攻击面和漏洞暴露来改善安全态势。
如果出于某种原因,你无法使用 distroless 或 scratch 镜像,请选择最小的发行版。现代的不可变 Linux 发行版,如 Bottlerocket 和 Flatcar Container Linux,以及传统 Linux 发行版的最低版本,如 Ubuntu、Red Hat 或 Alpine,可以用作容器的基础镜像。虽然最小的镜像可以工作,但请记住,这种类型的镜像无法防止操作系统(OS)包中的漏洞。
强化容器镜像
容器镜像强化增加了防御层,允许你在容器内安全地运行应用程序,同时还减少了安全弱点和攻击面。为工作负载构建加固的容器镜像非常重要,因为未加固的镜像会使工作负载面临一系列风险,包括向容器主机泄露信息和权限提升。
以下是一些强化容器镜像的方法。
——仅使用来自可靠来源的基本镜像,例如官方 Ubuntu 或红帽发布频道。
——根据发布的信息仔细检查镜像的哈希,即使它来自可信来源。攻击者在基本镜像中嵌入恶意代码,然后在 Docker Hub 等存储库中提供该镜像并不困难。
——最小化基础镜像。它们应该只包含应用程序的运行时依赖关系。
——按照最小权限原则(尽可能以非根用户身份运行容器),以最小的必要权限运行容器。这样,攻击者将更难逃离容器(CVE-2020-15257 漏洞就是如此)。
——使用容器镜像签名验证镜像。虽然 Kubernetes 原生不包括容器镜像验证工具,但你可以使用 Docker Notary 对镜像进行签名,并使用 Kubernete 许可控制器验证镜像签名。
如果使用 Docker 镜像,笔者建议如下:
——不要使用标签:如果移动或更改依赖库,标签(例如可变标签,如 latest 或 master)可能会导致应用程序稳定性问题。它们还可能导致 CI/CD 管道中的镜像扫描问题,因为它们会定期更新功能和修复。不要使用标签,而是将基本镜像版本固定在 Dockerfile 中(例如 ubuntu:20.08)。
——将层压缩为单个层:层显示开发历史,并可以显示敏感信息。由于使用 Docker 构建的容器镜像往往包括多个层,因此应该使用多级构建或选项——挤压(Docker API 1.25+中提供的实验性 Docker 守护进程)来压缩现有层。
扫描容器镜像
通过检查容器的文件系统和元数据,然后将收集的数据与来自各种可信来源(如国家漏洞数据库或私人情报来源)的漏洞信息进行比较,容器镜像扫描有助于确定镜像中是否存在漏洞组件。有很多可用的扫描工具,包括开源和商用。
确保镜像扫描工具扫描容器镜像中的所有操作系统包,并且了解应用程序使用的语言,以便能够扫描应用程序依赖关系。好的容器镜像扫描工具还应:
——检测文件系统中存在的敏感文件,如证书和密码。
——扫描二进制文件(如.elf 或.exe)。
——集成到你的 CI/CD 系统中。
——虚警率低。(请注意,在容器镜像扫描过程中可能会出现误报和漏报;应用程序和安全团队将需要分析这些信息并评估风险。)
虽然许多公共云提供商和容器注册服务提供商提供镜像和容器扫描服务,但其中许多提供商不扫描应用程序依赖关系,也只支持有限数量的操作系统版本。
由于产品中有关安全漏洞的信息是敏感数据,这将成为一大负担,因此在选择扫描工具之前,不要忘记解决数据安全和隐私问题。为了了解数据暴露的风险,了解扫描工具将收集哪些数据以及如何收集很重要。例如:它是只收集包元数据,还是将容器镜像上载到其 SaaS 服务?
为了确保该工具符合安全和/或合规团队制定的准则,还需要确定该工具是将收集的数据存储在本地还是作为 SaaS 的一部分存储在云中。如果使用商业工具,请务必检查合同,以了解在数据泄露的情况下有哪些损害赔偿条款;如果使用开源工具,请确保检查文档,以了解数据泄露的风险。
总结
本文中包含的提示和最佳实践可作为漏洞管理的良好起点。笔者建议阅读 O'Reilly 书籍《Kubernetes 安全和可观察性:保护容器和云本地应用程序的整体方法》第 3 章,以进一步详细了解这些最佳实践,并发现更多信息。