前言
当你在当地的杂货店购买包装好的食品时,你可能会检查上面列出的成分列表,以了解其中含有什么,确保你不会不经意地摄入你不希望吃的成分或已知对健康有不良影响的成分。但当你购买或使用软件产品时,你是否也有这样的思考方式?你是否清楚地了解构成该软件的各个组件,并知道其中是否有任何已知的漏洞?如今的典型软件应用都是使用许多开源软件库和可重复使用的第三方代码构建的。尽管这提高了开发者的生产力和他们快速交付新功能的能力,但在生产环境中也引入了额外的安全风险,因为开发者对第三方代码中的安全漏洞了解得较少,控制力也更弱。
Synopsys发布了其2023年开源安全和风险分析报告(OSSRA),报告显示96%的扫描过的商业代码库中含有开源代码,而代码库中的76%的代码是开源的。OSSRA的另一个观点是,48%的代码库包含高风险的漏洞。这表明现代软件应用在很大程度上依赖可能存在漏洞的开源代码,因此了解应用中使用的组件非常重要。应用程序可能声明其直接依赖项,而这些依赖项依赖于其他包,导致有传递依赖性,这使得检测应用程序使用的每个库或包变得极为困难。嵌入在数千个组织中部署的应用程序中的单个开源或专有软件组件有可能导致广泛的安全影响。现代软件供应链的复杂性和不透明性使其成为黑客发动供应链攻击的有利工具,影响大量的组织。Sonatype在2022年的软件供应链年度报告中发现,过去3年软件供应链攻击的平均年增长率达到742%。2020年的SolarWinds攻击就是一个供应链攻击的例子,该攻击导致了全球各地的组织,包括美国联邦政府的IT系统被攻破。为应对日益增加和复杂化的网络攻击,拜登总统于2021年5月签署了第14028号行政命令。该命令提高了国家的网络安全能力,特别关注增强软件供应链的安全。
需要实施多种机制来提高软件供应链的信任和安全性。之前发布的AWS文章主要帮助客户理解软件供应链安全的背景,即真实性和来源。文章描述了如何简化确保来自受信任方的容器镜像用于镜像构建和部署的过程。AWS还宣布推出AWS Signer Container Image Signing,这是一种新功能,使客户得到了AWS原生的支持,用于签名和验证存储在像Amazon Elastic Container Registry(Amazon ECR)这样的容器注册表中的容器镜像。
本文的重点是软件供应链的透明性,以及如何使用软件物料清单(SBOM)为您的容器镜像中的软件包提供可见性,从而使您能够迅速且轻松地确定您的容器化应用是否存在新发现的漏洞的潜在风险。
SBOM是什么,为什么重要?
SBOM(软件物料清单)是一个正式的、机器可读的记录,记录了构建软件产品所使用的所有库、模块和依赖性,以及这些组件之间的关系。这些组件可以是开源的或专有的、免费的或付费的,可从公共或私有的有限访问仓库获取。SBOM的记录旨在在组织之间共享,这样软件产品的购买者或消费者可以对供应链中不同方提供的组件进行透明度查看。例如,容器镜像的SBOM可以提供用于构建该镜像的所有组件的清单。这包括操作系统包、任何特定应用的依赖性或库及其版本、供应商和许可证信息。
SBOM的概念在开源社区已经存在了十多年,在商业软件中甚至存在得更久;但由于美国行政命令14028的原因,它现在正越来越受到关注。根据Linux基金会2022年的研究报告,对412个全球组织进行了调查,78%的组织预计在2022年将产生或消费SBOM。
组织使用SBOM的主要好处是:
- 了解应用程序的所有依赖性
- 识别并避免使用已知漏洞的软件组件
- 识别使用具有新发现漏洞的特定组件版本的应用程序或软件
- 管理许可证合规性要求
在AWS中,大多数客户工作负载都是从某种打包环境开始的,比如Amazon Machine Images (AMIs)、容器镜像或AWS Lambda zips。SBOM为您提供了一个简单且机器可读的方法,快速发现在给定环境中运行的是哪些软件。因为SBOM是以标准的机器可读格式创建的,您可以使用漏洞扫描器读取SBOM并检测已知漏洞的组件。例如,Grype是一个开源的容器镜像和文件系统的漏洞扫描器,它可以将SBOM文件作为输入进行快速的漏洞扫描。您可以在您的持续集成和持续交付(CI/CD)流水线中集成漏洞扫描工具,以确保已知漏洞的软件组件不会进入您的软件构件。但是,当一个新的零日漏洞,如Log4Shell被公开,您急于评估这个漏洞对您的组织的风险时该怎么办?
零日漏洞在定义上没有立即可用的修补程序或解决方案(例如,Log4j利用),因此它们往往是严重的漏洞。坏蛋会立即尝试利用这个漏洞来访问您的IT系统。在这种情况下,您希望快速且轻松地找出在您的组织中正在使用的带有漏洞的软件组件在哪里,然后评估风险并优先处理行动事项,以减轻与组件供应商提供补丁的努力无关的风险。您可以确定哪些软件是不受影响的,并只关注受影响软件的缓解行动。这就是SBOM可以非常有效地根据其在组织中的使用情况,量化与一个脆弱组件相关的风险的地方。
在这篇文章中,我们介绍了一种使用SBOM来查找在您的Amazon EKS集群中运行且内部包含有漏洞的软件组件的容器镜像的方法。这个解决方案涵盖了使用SBOM的一些关键考虑因素,例如为容器镜像自动生成SBOM、为SBOM清单提供中央化存储,以及在需要时快速检索清单的能力。
解决方案概览
下图描述了解决方案的架构。目前最受欢迎的SBOM格式的开放标准是SPDX和CycloneDX。大多数用于生成SBOM的工具都支持这两种格式。亚马逊网络服务(AWS)最近为Amazon Inspector服务引入了一个功能,该功能可以为组织内所有由Amazon Inspector监控的资源(包括Amazon ECR中的容器镜像)自动和集中地生成SBOM。Amazon Inspector的SBOM功能支持CycloneDX和SPDX格式。您可以了解更多关于使用Amazon Inspector导出SBOMs的信息。
本文的解决方案使用开源项目Syft,以SPDX JSON格式生成容器镜像的SBOM。许多客户使用第三方容器安全解决方案,而不是Amazon Inspector。Syft提供了一个有效的、开源的创建SBOM的替代方法。SPDX是一个用于通信SBOM信息的开放标准,包括与特定版本的软件包关联的组件、许可证和版权。在这些SBOM格式中,SPDX的存在时间最长,v1.0版本早在2011年8月就发布了。与Amazon Inspector类似,我们的解决方案也将生成的SBOM存储在Amazon Simple Storage Service (Amazon S3) 桶中进行分析。
生成SBOM的流水线 – 该流水线使用AWS CodeBuild实现,并在向您的AWS帐户中的任何Amazon ECR存储库推送新图像时触发。Amazon ECR是一个完全托管的容器注册表,使开发人员能够轻松共享和部署容器图像和工件。当图像成功地推送到存储库时,Amazon ECR会发出事件。请注意,通过Amazon EventBridge的Amazon ECR事件是以尽力而为的方式交付的,这应该纳入生产环境的考虑。关于通过Amazon EventBridge的AWS服务事件交付的更多详细信息可以在此找到。事件交付给Amazon EventBridge,这是一个无服务器服务,用于构建事件驱动的应用程序。您可以在Amazon EventBridge中定义规则,匹配传入的事件,并将它们发送给目标进行处理。在此解决方案中,Amazon EventBridge规则定义为模式,以匹配图像成功推送到存储库的事件,然后将此事件交付给AWS CodeBuild作为目标。
{
"source": ["aws.ecr"],
"detail-type": ["ECR Image Action"],
"detail": {
"action-type": ["PUSH"],
"result": ["SUCCESS"]
}
}
事件包含了存储库名称、图像摘要和图像标签等详细信息,AWS CodeBuild流水线可以使用这些信息在构建阶段从Amazon ECR存储库中拉取新图像。然后使用Syft为下载的图像生成SPDX JSON格式的SBOM。构建阶段的最后一步是将SBOM JSON上传到Amazon S3桶。
此组件演示了如何使用Amazon ECR、Amazon EventBridge和AWS CodeBuild创建无服务器的CI/CD流水线。有关传送到Amazon EventBridge的Amazon ECR事件的列表,请参考文档。
- 现有容器图像的SBOM – 一旦您在容器构建流水线中加入SBOM生成,每个新构建的容器图像都会在Amazon S3桶中有一个对应的SBOM文件。那么已经构建的图像呢?在此解决方案中,我们提供了一个AWS CodeBuild项目,您可以从AWS控制台或AWS命令行界面(AWS CLI)触发它作为一次性构建。此组件会发现您帐户中的所有Amazon ECR存储库,并为该帐户和指定区域中已经存在的所有图像生成SBOM。
- CronJob用于发现在Amazon EKS集群中运行的图像 – 此组件可以部署为在任何Amazon Elastic Kubernetes Service (Amazon EKS) 集群上的定时CronJob。工作发现所有命名空间中运行的所有pod,并创建一个包含pod中所有容器图像的JSON文件。该工作使用官方的Kubernetes python客户端来调用应用程序编程接口(API)服务器。JSON文件上传到Amazon S3桶。Amazon S3上的文件总是被覆盖,这意味着对于给定的Amazon EKS集群,只有一个图像列表文件。
- SBOM分析 – 该分析组件可用于查询存储在Amazon S3上的SBOM和图像列表文件。此组件包括:
- AWS Glue Crawler和Data Catalog – AWS Glue Data Catalog是一个索引,指向您数据的位置、模式和运行时指标。AWS Glue爬虫配置为使用包含SBOM和图像列表文件的Amazon S3桶作为数据源。爬虫从JSON文件中发现模式,用于填充带有表格的AWS Glue Data Catalog。
- Amazon Athena – Amazon Athena是一种交互式查询服务,可以轻松地使用标准SQL直接在Amazon S3中分析数据。我们使用Amazon Athena查询存储在Amazon S3中的SBOM和图像列表JSON文件,并识别包含易受攻击的包的图像。
以下是部署该解决方案所需的先决条件:
- 一个 AWS 账户
- 命令行终端
- 安装并使用您的 AWS 凭据配置的 AWS CLI
- 亚马逊弹性 Kubernetes 服务(Amazon EKS)集群
- 在您的本地机器上安装并配置的 Terraform 版本 1.3.9 或更高版本
- 已安装的 Git
- 已安装的 eksctl
- 已安装的 kubectl
操作指南:本节描述如何部署上述解决方案架构
我们将执行以下任务:
- 克隆GitHub仓库并使用Terraform部署解决方案架构
- 在Amazon EKS集群上部署CronJob以发现正在运行的容器的镜像
- 使用SBOM和正在运行的图像数据为AWS Glue目录填充表
- 运行Amazon Athena查询来识别使用易受攻击的库和软件包的图像
使用Terraform部署解决方案架构:
- 首先克隆示例GitHub仓库:
git clone https://github.com/aws-samples/amazon-eks-use-sbom-to-find-container-image-with-vulnerable-software.git
在GitHub仓库的根目录中,导航至terraform目录
cd terraform
- 使用文本编辑器编辑Terraform目录内的tfvars文件。确保为aws_region变量提供正确的值,以指定您希望部署的AWS区域。您可以接受其他变量的默认值,或根据需要进行更改。
- 确保用于运行Terraform的主体具有部署所有资源所需的权限。有关提供AWS身份验证凭据的信息,请参考Terraform文档。
- 运行以下命令以确认您已在AWS CLI上配置了默认区域。
aws configure list
- 提供AWS凭据和默认区域的推荐方法是使用环境变量。例如,您可以使用AWS_PROFILE环境变量为运行terraform提供AWS CLI配置文件。请参考AWS CLI文档以获取配置细节。
- 初始化您的工作目录。
terraform init
- 预览terraform将在您的AWS帐户中部署的资源。
terraform plan
- 通过运行以下命令并在提示时选择是来批准创建资源。
terraform apply
Terraform输出了两个值,您需要复制这些值,以便在Amazon EKS上部署CronJob的下一步。您可以随时运行命令terraform output以获得输出值。
部署Amazon EKS的CronJob
我们假设您已有一个现有的Amazon EKS集群,并在您的机器上安装了Kubernetes CLI以与集群交互。以下步骤描述如何在Amazon EKS集群上部署CronJob组件。
在Git仓库的根目录中,导航到eks-image-discovery目录。然后按照以下步骤在Amazon EKS集群上部署CronJob。
cd eks-image-discovery
- 按照AWS文档为EKS集群创建IAM OpenID Connect (OIDC)提供者。
- 使用eksctl为服务帐户创建一个AWS Identity and Access Management (AWS IAM)角色。此AWS IAM角色将被Amazon EKS CronJob使用,将正在运行的容器图像列表写入Amazon S3 bucket。替换从Terraform输出中复制的集群名称和策略Amazon资源名称(ARN)。策略是Terraform模块创建的资源之一。按照最少权限原则,该策略仅为SBOM S3 bucket资源授予PutObject权限。
{"Statement": [{"Action": ["s3:PutObject"],"Effect": "Allow","Resource": "arn:aws:s3:::sbom-bucket-20230606154820770300000004*"}],"Version": "2012-10-17"}
执行以下命令创建IAM服务帐户:
{
"Statement": [{
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::sbom-bucket-20230606154820770300000004*"
}],
"Version": "2012-10-17"
}
eksctl create iamserviceaccount --name image-discovery-job --namespace sbom-image-discovery --cluster <<your EKS cluster name>> --attach-policy-arn <<policy ARN from Terraform output>> --approve
- Terraform将在您的帐户中创建一个Amazon ECR仓库eks-image-discovery,以存储Amazon EKS CronJob的镜像。转到AWS控制台中的Amazon ECR仓库并选择查看推送命令的按钮。按照这些命令构建并将Amazon EKS CronJob的docker镜像推送到Amazon ECR仓库。从AWS控制台复制新推送的镜像的统一资源标识符(URI)。
- 导航到eks-image-discovery内的config目录。这包含一个您需要编辑以部署CronJob的Kubernetes清单文件。用任何文本编辑器打开eks-image-discovery.yaml文件。
- 编辑image字段,将其更改为您在上一步中复制的图像URI。
- 更新Amazon S3 bucket名称的环境变量配置。使用从Terraform输出中复制的bucket名称。
- 使用您的集群名称更新Amazon EKS集群的环境变量名称。
- 可以选择性地更新CronJob。默认情况下,作业每5分钟运行一次。
- 使用kubectl应用清单文件。
kubectl apply -f config/eks-image-discovery.yaml
填充AWS Glue目录
为了填充AWS Glue目录,我们需要生成SBOM文件。将新图像推送到您帐户中的任何Amazon ECR仓库(即,您部署解决方案的区域)。这应该触发AWS CodeBuild任务自动为新推送的图像生成一个SBOM文件。请验证AWS CodeBuild任务已成功完成。
如果您想为存储在您帐户的Amazon ECR仓库中的现有图像生成SBOM文件,请执行此步骤。导航到AWS控制台中的AWS CodeBuild服务。转到项目sbom-codebuild-project-one-off并开始新的构建。默认情况下,构建任务扫描您帐户中指定区域的所有Amazon ECR仓库,并为仓库中存储的所有图像创建SBOM文件。如果您想为存储在特定仓库中的现有图像生成SBOM文件,则可以根据代码仓库中提供的说明更改Terraform变量one_off_scan_repo_settings。
导航到AWS控制台中的Amazon S3服务。验证AWS CodeBuild任务创建了SBOM文件,以及Amazon EKS CronJob在为解决方案创建的Amazon S3桶中创建了正在运行的图像文件列表。Amazon S3桶的名称是Terraform自动化的输出之一。
现在Amazon EKS集群上的SBOM文件和正在运行的图像列表已经在Amazon S3上创建,下一步是运行AWS Glue爬虫访问Amazon S3数据源,提取元数据,并在AWS Glue Data目录中创建表定义。导航到AWS控制台中的Glue服务。转到Crawlers并运行爬虫sbom_crawler。如果Amazon S3桶中有大量的SBOM文件,则爬虫将需要几分钟来处理文件。
等待爬虫成功完成。完成后,导航到AWS Glue服务控制台中的Databases并选择sbom_db。您应该看到在数据库中创建了两个叫做sbom和eks_running_images的表。
运行示例的Amazon Athena查询
我们将使用Amazon Athena,这是一个无服务器的查询服务,允许客户使用标准SQL分析存储在Amazon S3中的数据。在本节中,我们将讨论一些客户可能想要找出易受攻击的软件包的情景,并提供可用于扫描SBOM文件的Amazon Athena查询。
要开始使用Amazon Athena查询sbom_db数据库中的表,请按照以下步骤操作:
- 在您的AWS管理控制台中打开Amazon Athena控制台。
- 确认您的数据源设置为AwsDataCatalog – 这应该是默认选择。
- 接下来,从位于查询编辑器左侧的数据库下拉列表中定位并选择sbom_db数据库。
- 在运行您的第一个查询之前,导航到位于控制台右上角的设置标签。在查询结果位置下,输入或选择希望存储查询结果的Amazon S3位置。记得在设置位置后选择保存。您可以在Amazon Athena文档中找到关于“查询结果位置”的更多信息。
- 现在您可以返回到查询编辑器,开始在sbom_db上编写并执行您的查询。 您的Amazon Athena控制台应该看起来与以下图示类似
Amazon Athena直接从Amazon S3查询数据,因此请确保您的Amazon Athena服务具有访问指定Amazon S3桶的必要权限。
在接下来的部分中,让我们深入探讨应用于SBOM的Amazon Athena的强大查询功能。为了便于更好地理解,我们将引导您了解三个实用示例:
- 查找带有特定包的容器映像:这有助于您识别Amazon EKS集群中包含特定包的容器映像,而不考虑其版本。
- 识别带有某个包和版本的容器映像:这扩展了前一个示例,使您能够通过包和您的Amazon EKS集群中正在运行的特定版本来精确定位容器映像。 您可以在我们的GitHub仓库中找到更多的Athena查询(SQL)示例。
这些示例仅仅触及了Amazon Athena功能的皮毛。借助Amazon Athena的强大SQL功能,我们鼓励您根据可用的SBOM数据编写适合您需求的查询。这不是一个限制性的框架,而是一个启发创意和在您的软件供应链管理中进行定制的跳跃点。
特定包中的漏洞 – 搜索特定包(不含版本)
此示例查询允许用户输入带有通配符字符(%)的包名称,并检索其Amazon EKS集群上所有包含指定名称的包的容器图像。从下面的示例中复制查询,并替换<PACKAGE_NAME>为您想要找出在您的Amazon EKS集群上运行的任何容器图像中是否存在(或不存在)的包名称。
在我们的示例中,考虑在您的Amazon EKS集群中部署的容器eks-image-discovery,其中包含一个名为boto3的包。要找到此包,您需要在Amazon Athena查询的末尾附加WHERE package.name LIKE ‘%boto3%’。这种方法增强了您在Amazon ECR容器图像中的任何包的可发现性。此解决方案的优点是它使用SQL语言,这使您可以根据可用的SBOM和运行的Amazon EKS图像来定制查询,满足您的需求。这使其成为了解您的软件供应链的强大工具。
示例:
SELECT
name AS sbom_image_name,
package.name AS sbom_package_name,
package.sourceInfo AS sbom_sourceInfo,
package.versionInfo AS sbom_version_info,
eks_running_images.image_name AS eks_running_image,
eks_running_images.pods
FROM
sbom
CROSS JOIN UNNEST(sbom.packages) AS t (package)
INNER JOIN eks_running_images
ON sbom.name = eks_running_images.image_name
WHERE package.name LIKE '%<PACKAGE_NAME>%'
示例输出:
# sbom_image_name sbom_package_name eks_running_image pods sbom_sourceInfo sbom_version_info
1 <SBOM_CONTAINER_IMAGE_NAME> <PACKAGE_NAME> <EKS_RUNNING_CONTAINER_IMAGE> <PODS_RUNNING_IMAGE> <SBOM_SOURCE_INFORMATION> <SBOM_PACKAGE_VERSION_INFO>
示例截图:
针对特定包和版本的漏洞 – 搜索特定包和版本
此示例查询允许用户搜索当前在其环境中运行的特定包和版本。例如,针对特定包和版本宣布了一个漏洞。您可以使用此查询来查找包含该特定包和版本的镜像。
示例查询:
SELECT
name AS sbom_image_name,
package.name AS sbom_package_name,
package.sourceInfo AS sbom_sourceInfo,
package.versionInfo AS sbom_version_info,
eks_running_images.image_name AS eks_running_image,
eks_running_images.pods
FROM
sbom
CROSS JOIN UNNEST(sbom.packages) AS t (package)
INNER JOIN eks_running_images
ON sbom.name = eks_running_images.image_name
WHERE package.name LIKE '%<PACKAGE_NAME>%'AND package.versionInfo LIKE '<PACKAGE_VERSION>'
在搜索包版本时,使用SQL通配符可以增加查询的灵活性。例如,如果您需要查找所有符合格式或版本(1.26.X)的版本,其中X可以是任何值,您可以使用以下AND语句(如上面的最后一行所示):
AND package.versionInfo LIKE '1.26.%'
示例输出:
# sbom_image_name sbom_package_name eks_running_image pods sbom_sourceInfo sbom_version_info
1 <SBOM_CONTAINER_IMAGE_NAME> <PACKAGE_NAME> <EKS_RUNNING_CONTAINER_IMAGE> <PODS_RUNNING_IMAGE> <SBOM_SOURCE_INFORMATION> <SBOM_PACKAGE_VERSION_INFO>
示例截图:
清理
为了避免将来产生费用,请通过运行以下命令删除为此解决方案创建的资源:
- 从存储库的根目录导航到
eks-image-discovery
文件夹。
cd eks-image-discovery
- 删除Amazon EKS CronJob及其关联的资源。
kubectl delete -f config/eks-image-discovery.yaml
- 删除AWS IAM服务帐户。
eksctl delete iamserviceaccount --name image-discovery-job --namespace sbom-image-discovery --cluster <<your EKS cluster name>>
- 清空Terraform为存储SBOM和运行图像文件创建的Amazon S3桶。如果桶不为空,Terraform将无法删除Amazon S3桶。使用Terraform输出的值替换桶名。如果您尚未复制桶名,请运行
terraform output
命令再次查看输出。
aws s3 rm s3://<<Bucket name>> --recursive
- 从存储库的根目录导航到
terraform
文件夹。
cd ../terraform
- 销毁Terraform创建的所有资源。
terraform destroy
按照以上步骤,您可以删除所有相关资源,从而避免额外费用。
结论
在本文中,我们向您展示了如何整合SBOM的使用,以增强软件供应链的透明度,并减轻运营环境中易受攻击的软件的风险。AWS Well-Architected Framework指定了一项安全最佳实践,即在管道中自动测试和验证安全控制。将SBOM生成纳入容器构建管道应该是另一个安全功能,以便在您的安全环境中检测易受攻击的软件包,防止部署包含特定软件包的软件,并验证各种第三方软件依赖的许可证。因此,采用SBOM是改善整体安全姿势的重要步骤。
此解决方案为许多可能性打开了大门。例如,它可以根据不同的组织需求进行调整,为更大的部署进行扩展,甚至可以用来增强现有的安全措施。
本文转载自https://aws.amazon.com/cn/blogs/containers/using-sbom-to-find-vulnerable-container-images-running-on-amazon-eks-clusters/,本文观点不代表墨知立场。