DevOps 中容器安全的 9 个最佳实践

深入了解DevOps中的容器安全

在DevOps实践中,容器技术并非新兴事物。它们本质上是虚拟的沙箱环境,承载着运行微服务,乃至大型应用程序所需的各类工具。

不妨将容器视为一种打包机制,它允许开发者从一个中心位置存储应用程序运行时所需的一切,例如运行时环境和二进制代码。

容器的优势在于其出色的可移植性,能够帮助开发者轻松地将应用程序从一个环境转移到另一个环境。例如,从本地计算机到虚拟环境,或从开发阶段到生产阶段。这极大地减少了因不同环境下的软件和配置差异而产生的问题。

Statista 的报告显示,全球已有50%的组织采用了容器编排技术。尽管这项技术因其诸多优点而日益普及,但如果缺乏有效的安全管控,容器也可能成为网络安全攻击的突破口。

CVE Details,一个知名的安全漏洞数据库,记录了截至目前62个Docker相关的安全漏洞。 这是否意味着我们需要最佳的开发实践来规避这些潜在的风险,并确保容器在DevOps流程中的安全?

本文将深入探讨容器安全的概念,剖析其面临的挑战,并为您在使用容器技术时提供最佳实践指南。

什么是容器安全?

容器安全是一个持续性的过程,它通过应用安全协议(包括工具和策略)来保护容器及其运行环境,使其免受潜在威胁的侵害。

这些威胁如果不加以控制,可能会对您的应用程序、基础设施、运行时环境、系统库、操作系统内核等关键组件造成损害。

考虑到容器的短暂性和动态部署特性,自动化安全措施并将其融入软件开发生命周期(SDLC)的每一个阶段至关重要。

另请参阅:Kubernetes Kops 初学者简介

容器安全面临哪些挑战?

尽管容器技术带来了诸多优势(例如加速软件交付速度),但其安全挑战也不容忽视。容器本身缺乏自我保护能力,因此需要额外的安全措施。

这是因为容器通过托管操作系统(OS)访问硬件资源。这意味着一个容器可能依赖多个底层容器镜像,从而扩大了潜在的攻击面,增加了安全风险。

首要挑战之一是不正确的容器配置。开发人员有时会忽略自定义配置,而是直接使用默认设置,而这些设置可能存在安全缺陷,例如暴露的不安全端口、泄露的凭据(密码和身份验证令牌),以及容器运行时过度赋予的权限(例如以root身份运行)。这些默认配置在未被覆盖的情况下,会为攻击者提供可乘之机。

其次是容器基础设施漏洞。容器中内置的软件包(应用程序代码、库、配置等)或主机操作系统上的软件包都可能引入漏洞。敏感性问题可能在应用程序生命周期的任何阶段出现,例如,当外部依赖项被构建到容器镜像中时、当开源库作为应用程序的一部分被安装时,以及当来自第三方容器注册表和主机的容器基础镜像可以通过网络和端点被利用时。

容器工作负载的可见性也是一个重要的挑战。由于容器的高度动态性,监控工具很难追踪正在运行的容器以及检查其网络行为。提高可见性对于预防违规行为,并在出现问题时缩短响应时间至关重要。

此外,如果持续集成/持续交付(CI/CD)管道的任何环节(无论是应用程序代码还是容器工作负载基础设施)不安全,容器都将受到影响。虽然开发者需要在应用程序生命周期结束时解决安全问题,但在开发的每个步骤中都注重安全,可以有效地保护您的应用程序免受潜在威胁。

哪些工具可以解决容器安全挑战?

通过使用安全工具实施容器安全性和完整性,您可以确保企业级解决方案的部署安全。这些工具能够扫描漏洞,并持续监控攻击、错误或其他潜在问题。

无论您是在寻找开源容器安全工具还是商业解决方案,它们都服务于相同的目标,即通过审计您的容器基础设施,并针对常见的漏洞和暴露(CVE)进行扫描。

以下是一些可以尝试的工具:Pingsafe Editors Choice、Datadog Cloud SIEM、Anchore、Sophos Cloud-Native Security、Bitdefender GravityZone、Sysdig secure、Aqua Security 以及RedHat Advanced Cluster Security for Kubernetes。

另请参阅:用于查找漏洞的11个容器安全扫描器

容器安全最佳实践

尽管容器安全面临上述挑战,但您仍然可以通过实施以下最佳实践,在应用程序生命周期的各个阶段优化容器安全。

保护您的镜像

您使用容器镜像来创建容器。哪怕是最轻微的配置错误或恶意行为,都可能导致生产环境中出现安全漏洞。您可以通过以下方式应对:

  • 使用可信的镜像 – 当您不从头开始创建镜像时,请务必选择来自可信来源的镜像。公共存储库如Docker Hub中存在着大量镜像,其中一些可能包含恶意软件或配置错误。
  • 仅包含必要的组件 – 如果您的应用程序不需要某些组件,最好将其删除。例如,UNIX系统通常会自带“awk”和“sed”二进制文件。
  • 将您的应用程序包含在容器镜像中 – 容器镜像包含操作系统(OS)和正在运行的应用程序的子集。对于容器中包含的每个工具和库,都存在潜在的威胁。解决此问题的最佳方法是将应用程序包含在容器镜像中,可以通过静态编译的二进制文件来实现,该文件包含所有必要的依赖项。

自动扫描漏洞和管理

对容器和主机进行定期的漏洞扫描和管理,有助于在应用程序生命周期的任何阶段检测到漏洞。

您可以执行代码扫描来检测错误,并进行静态应用程序安全测试(SAST)来查找应用程序代码中的漏洞。软件组成分析(SCA)可以提供对开源软件组件的可见性,生成软件物料清单,从而可以根据已记录的开源漏洞进行交叉引用。

此外,镜像扫描可以分析内容和容器镜像构建过程的敏感性。使用诸如 Clair 等工具,您可以扫描已知漏洞。或者,采用动态应用程序安全测试(DAST),它可以根据容器的行为指出安全风险。DAST 工具还可以执行主机扫描,检查容器主机组件(主机内核和操作系统)是否存在配置错误。

虽然上述措施是在容器生命周期的持续过程中采取的,但您也可以采用“左移”理念,即从开发生命周期的早期阶段就开始实施安全性。如果选择这种方法, Trivy 是一个不错的工具。

保护容器注册表的安全

容器注册表是存储和分发镜像的有效集中方式。通常,组织会在公共或私有注册表中存储数千个镜像。采取多项措施可以确保所有团队成员和协作者都使用无漏洞的镜像。

首先,实施用户访问控制(针对私有注册表),明确谁可以发布和访问镜像。这是一项基本的安全措施,可以防止未经授权的人员发布、修改或删除您的镜像。

接下来是对镜像进行签名,将每个镜像与签名者关联,从而使替换受损镜像变得更加困难。您可以利用Docker内容信任技术,为从注册表发送和接收的数据添加数字签名。最后,请务必(持续)扫描镜像,以检测任何严重漏洞。

监控容器

您可以通过可观察性工具优化容器工作负载的可见性。这些工具应具备监控和测试所有组件漏洞的能力,并为容器化环境启用实时事件记录。

可观察性工具通过审核容器堆栈中所有组件的指标和日志,并分析是否存在异常来检测威胁。通过这种方法,您可以在发现配置错误后立即进行纠正。

要收集资源使用指标,可以使用 cAdvisor 或 kube-state-metrics 等工具。要监控容器的活动和集群的性能,可以使用 Grafana 或 Prometheus 等工具。

如果要分析容器之间的网络流量,可以使用 Wireshark 或 tcpdump。如果您使用托管的 Kubernetes 服务(如AKS),则可以使用Azure Monitor来跟踪资源和安全威胁。

此外,Azure Log Analytics 可以收集和分析您的 AKS 资源。如果您选择Amazon EKS,Amazon CloudTrail非常适合记录和观察; 您也可以使用Amazon CloudWatch。

实施网络安全

网络安全控制措施可以有效防止对容器的未授权访问。这里采用的标准做法是网络分段,它能够隔离容器,限制它们仅能访问必要的服务。

如果在Kubernetes上运行容器化应用程序,您可以使用K8s网络策略来配置集群中传入和传出的Pod流量。反过来,这将根据标签限制特定Pod的流量。

可以为Pod通信增强传输层安全性(TLS)。您可以选择TLS或安全套接字层(SSL)技术,来实现API服务器与其他组件之间的安全通信。如果您还想限制进入集群的流量,负载均衡器是一个很好的解决方案。

如果您的集群包含微服务,您可以使用Meshery或Linkerd等服务网格工具来确保流量安全。最后,如果使用云产品来托管集群,请务必保护您的网络。

如果使用Azure Kubernetes服务(AKS),请使用网络安全组(NSG)进行流量管理。如果使用Amazon Elastic Kubernetes Service(EKS),最合适的选择是Amazon Virtual Private Cloud(VPC)安全组。

减少攻击面

最大限度地减少攻击面有两个好处:提高服务速度并降低安全漏洞的风险。

通过使用多阶段构建,您可以创建具有更小攻击面、更快的启动速度和更高性能的轻量级镜像。有多种解决方案可以实现这一点。如果您使用的是Linux,则可以使用Alpine Linux、BusyBox或Tiny Core Linux。

对于Ubuntu,可以使用Ubuntu Minimal。您还可以使用Scratch(一种特殊的Docker镜像)——本质上是一个开放容器,从头开始构建简约的镜像。

限制容器权限

这里采用的原则是,提供执行给定任务的最低权限。当容器以root身份运行时,会授予用户各种操作权限,例如在操作系统上安装软件包或读写权限。

如果容器遭到攻击,攻击者可能会利用容器运行时的权力来升级权限。因此,有两种可行的解决方案:您可以无根模式下运行容器,或者将Linux内核的功能限制为容器工作负载所需的功能。

安全管理密钥

您的容器和Docker配置文件中不应包含任何密钥。密钥包括证书、密码、应用程序接口(API)密钥和令牌。虽然这是一种最佳实践,但您经常会发现这些密钥被硬编码到构建过程或源代码镜像中。

在这种情况下,即使容器已被删除,敏感数据也会进入容器并缓存在中间容器层中。针对这种情况,最好的方法是部署一个密钥管理解决方案,例如AWS Secrets ManagerVault,用于存储和管理密钥凭证。

赋能您的团队

作为最后一道安全防线,对您的团队进行最佳安全实践培训至关重要。这意味着您的所有团队成员都能够识别并响应安全威胁。

实现这一目标的一个好方法是将容器安全添加到团队入职流程中。提供实践培训、持续学习和定期安全评估,让您的DevOps团队了解最新的安全趋势,从而使他们与众不同。

最后思考

容器安全是软件开发生命周期中一个至关重要的持续过程。处理此问题的最佳方法是将安全性从应用程序代码集成到容器运行时、主机操作系统和底层网络基础设施中。

您可以通过遵循战略计划来实现此目标,该计划包括验证容器,并仅使用来自可信来源的容器。进行容器加固,以确保其中仅包含必要的服务。引入可通过监控工具轻松实施的日志记录方法。对网络进行分段,以便将容器与整个基础设施隔离开来。

始终对您的镜像进行签名,以验证通过您的服务输入和输出的数据。此外,您还应定期进行扫描和渗透测试,以检查是否存在任何漏洞并立即采取纠正措施。随着技术格局不断发展,始终保持对最新安全实践的了解。

接下来,深入了解如何实现安全自动化。