【翻译】安全的软件供应链:规模化的良好实践

特邀文章,原载于 Contino Engineering 博客,作者Dan Chernoff

2021年第一季度,供应链攻击上升了42%[1],而且正在变得更加普遍[2]。为了应对像Solar Winds[3]、Kaseya[4]这样的安全软件供应链泄露事件,以及其他不太公开的泄露事件[5],拜登政府发布了一项行政命令,其中包括旨在改善联邦政府对网络威胁的防御的指导。随着这一切的发生,不可避免地出现了一系列的博客文章,详细介绍了软件供应链以及如何保护它。云原生计算基金会最近发布了一份关于软件供应链安全的白皮书[7],这是对当前保障软件供应链安全的最佳实践的出色总结。

本文内容的起源是为Contino客户实施安全供应链模式和实践所做的工作。这项工作的核心目标是:实施一个与管道无关的解决方案,确保管道的安全,并为企业实现安全交付。我们将在每一节中谈一谈为什么我们选择了这些工具,以及它们是如何支持最终目标的。

当我们开始我们的旅程时,我们将首先谈谈什么是安全的软件供应链,以及为什么你应该有一个安全的软件供应链,以便为博文的其余部分设置背景。但是,让我们假设你已经决定你的软件供应链需要安全,并且你想为你的企业实施这一能力。所以,让我们开始行动吧

预备工作

在你开始寻求为你的软件建立规模化的出处之前,有一些团队应该已经准备好了的要素。在这里,我们不会深入研究任何一个要素,而只是列出并简要介绍一下它们。

集中的源代码控制,Git是目前最流行的选择。这可以确保开发团队有一个单一的真相来源。除了拥有源代码控制,团队还应该对他们的Git提交进行签名

静态代码分析。通过使用污点分析和数据流分析等技术,确定 "静态"(非运行的)源代码中可能存在的漏洞。分析和结果需要被纳入到开发的节奏中。

漏洞扫描。实施自动化工具,扫描所构建的应用程序和容器,以识别编译后的、有时正在运行的应用程序中的潜在漏洞。

Linting是一种分析源代码的工具,用于标记编程错误、bug和风格错误。提示对于减少错误和提高整体代码质量非常重要。这反过来又加速了开发。

CI/CD管线。新的代码修改被自动构建、测试、版本化,并交付给工件库。然后,一个管道会自动将更新的应用程序部署到你的环境中(例如,测试、暂存、生产等)。

工件。提供对CI/CD系统构建的工件的管理。工件库可以帮助你的工件的版本和访问控制。

基础设施即代码(IaC) 是通过代码管理和配置基础设施(如虚拟机、数据库、负载平衡器等)的过程。与应用程序一样,IaC为基础设施应该是什么样子提供了一个单一的真理来源。它还提供了在部署到生产之前进行测试的能力。

自动化......嗯,一切。 人工循环系统是不确定的。他们很容易出错,这可能并将导致停工和安全漏洞。人工系统还抑制了平台的快速扩展能力。

什么是安全的软件供应链

软件供应链包括任何用于创建你的最终软件产品的东西,以及你用来向客户交付产品的机制。这包括像你的源代码,你的构建系统,第三方库,部署基础设施,或交付库。

属性。

  • 建立出处 - 建立出处的一部分是确保任何由客户创建和访问的工件应该能够一直追溯到合并最新提交的开发人员的血统。另一部分是能够证明(或证明)在这个过程中的每一步,软件、组件和其他用于创建最终产品的材料是没有被篡改的。
  • 信任 - 下游系统和用户需要一个机制来验证正在安装或部署的软件是来自你的系统,并且正在使用的版本是正确的版本。这可以确保恶意的工件没有被替换,或者旧的、脆弱的版本没有被重新标记为当前版本。
  • 透明性- 应该很容易看到创建最终工件的所有步骤的结果和细节。这可以包括诸如测试结果、漏洞扫描的输出等内容。

安全软件供应链的关键因素

让我们仔细看看需要在你的管道中分层的东西,以建立出处,实现透明度,并确保防篡改。

下面是一个典型的管道,它可以创建一个容器化的应用程序。我们将使用这个简单的管道,并在讨论时添加元素。

Pipeline diagram: code -> build -> test -> build image -> verify -> deliver

使用in-toto建立证据

我们旅程的第一步是建立通过管道构建的工件没有被篡改,并以可靠和可重复的方式做到这一点。正如我们前面提到的,其中一部分是创建证据,作为验证的一部分。in-toto是一个开源工具,它可以创建管道步骤运行的工作空间的快照。

这些快照(用in-toto的术语说是 "链接文件")验证管道的完整性。in-toto的核心思想是材料和产品的概念,以及它们如何流动,就像在一个工厂里一样。流程中的每一步通常都有一些材料,将创造其产品。材料和产品的流动的一个例子是构建步骤。构建步骤使用代码作为材料,而构建的工件(jar、war等)就是产品。管道中的后一个步骤将使用构建的工件作为材料,并产生另一个产品。通过这种方式,in-toto允许你将材料和产品联系在一起,并识别材料是否在管道步骤中或之间被篡改过。例如,如果在构建步骤中构建的工件在测试前发生了变化。

Pipeline diagram: code -> build -> test -> build image -> verify -> deliver. Using product and material flow in process and in-toto verification to verify

在流水线结束时,in-toto对照in-toto布局(认为是Jenkins文件的证明)评估链接数据(在每个步骤创建的证明),并验证所有的步骤都是正确的,由批准的人或系统完成的。这种验证可以在管道的产品(容器、战争等)需要验证的任何时候运行。

建立出处的关键启示

in-toto运行在流程的每一步。验证过程中,证明与总体布局相比较。这个过程使消费者(用户和/或部署系统)有信心,建立的工件从开始到结束都没有被改变。

使用TUF建立信任

你可以使用内部验证来了解工件的交付或下载没有被修改。要做到这一点,你需要下载工件、构建过程中使用的in-toto链接文件、in-toto布局和公钥来验证这一切。这是一个很大的工作。一个更简单的方法是用一个能够集中信任的系统来签署产生的工件。这样做的最成熟的框架是TUF(更新框架)。

TUF是一个框架,它为人工制品的消费者提供保证,即下载或自动安装的人工制品来自你的系统,并且是正确的版本。如何实现这一目标的内涵不在本博文的范围之内。我们感兴趣的功能是验证工件是否来自于我们所期望的生产者,以及版本是否是期望的版本。

自己实现TUF是一个相当大的工作。幸运的是,一个 "开箱即用 "的TUF实现可以使用,即Docker Content Trust(又称Notary)。Notary可以对普通文件和容器进行签名。在我们的例子管道中,我们在构建时签署了容器镜像。这种签名允许任何下游系统或用户验证该容器的真实性。

Pipeline diagram: code -> build -> test -> build image -> verify -> deliver. Using product and material flow in process and in-toto verification to verify. Signing notary (container image) during build image time.

透明度 集中式数据存储

in-toto作为一个解决方案的差距之一是它创建的链接数据的持久化机制。这取决于实施in-toto的团队,在某个地方捕获和存储链接数据。每个步骤的所有有价值的元数据都可以被捕获并存储在构建系统之外。目标是双重的;第一是将链接数据存储在管道之外,使团队能够检索链接数据,并在需要对管道产生的工件进行验证时使用它。第二个目标是在管道外存储围绕构建过程的元数据。这使得团队能够在管道产生的数据上实现可视化、监控、指标和规则,而不一定需要将其保留在管道中。

Contino团队创建了元数据捕获工具,它是独立的,与管道无关的。我们选择编写一个简单的python工具,捕获元数据和管线内数据,并将其存储在数据库中。如果CI/CD平台是合理的标准,你很可能使用内置机制来实现同样的结果。例如,Jenkins LogStash插件可以捕获构建步骤的输出,并将数据持久化到一个弹性数据存储。

Pipeline diagram: code -> build -> test -> build image -> verify -> deliver. Storing metadata and using product and material flow in process and in-toto verification to verify. Signing notary (container image) during build image time.

PGP和签名密钥

in-toto和Notary的一个核心组件是用于签署和验证链接数据和工件/容器的密钥。in-toto使用PGP私钥来签署内部每个步骤产生的链接数据。这种签名确保了做这个动作的人或系统和链接数据之间的关系。它还确保如果链接数据以任何方式被改变或篡改,可以很容易地检测出来。

公证处使用使用Docker或公证处CLI生成的公钥和私钥。公钥被存储在公证数据库中。私钥签署容器或其他工件。

扩大规模

对于一小部分管道,手动实施和管理安全的软件供应链实践是很简单的。管理一个拥有数百甚至数千条管道的企业,需要一些额外的自动化。

自动化in-toto布局创建。如 前所述,in-toto有一个类似于Jenkins文件的文件,规定什么人或系统可以完成一个管道步骤,材料和产品流程,以及如何检查/验证最终的工件。在这个布局中嵌入了可以执行步骤的人或系统的PGP密钥的ID。此外,布局是内部签名的,以确保一旦布局被创建,任何篡改都能被发现。为了大规模地管理这些,布局需要按需自动创建/再创建。我们将此作为一个管道,在对创建布局的代码进行修改时自动运行。该管道的输出是布局,它被视为工件本身。

对待in-toto布局就像对待人工制品一样。in-toto支付是人工制品,就像容器、罐子等。布局应该被版本化,并且布局的版本与工件的版本相联系。这种版本化使工件在创建工件的时候可以用布局、链接文件和相关的密钥进行重新验证。

自动创建签名钥匙。自主系统所使用的签名钥匙应该通过自动化方式经常轮换。这样做限制了in-toto和Notary使用的签名钥匙被破坏的可能性。对于in-toto来说,这种频繁的轮换将需要自动重新创建in-toto的布局。对于公证处来说,循环使用签名钥匙将需要在我们实施新钥匙时撤销旧钥匙。

储存和使用来自秘密商店的签署密钥。 当生成供自动系统使用的签名密钥时,将密钥存储在像Hashicorp的Vault这样的秘密管理系统中是一个重要的做法。自动化系统可以在需要时检索签名密钥(如Jenkins、GitLab ci等)。集中存储签名密钥可以打击企业中的 "秘密蔓延",使管理更加容易。

管道应该是大致相似的。一 个单一的in-toto布局可以被许多管道使用,只要它们以相同的方式运作。例如,建立一个Java应用程序的管道,创建一个WAR作为工件,可能以大致相同的方式操作。如果这些管道足够相似,它们都可以使用相同的布局。

总结一切

使用这里的技术、模式和实践,Contino团队能够为企业提供一个MVP级的解决方案。该设计将能够扩展到成千上万的应用程序管道,并帮助确保企业的软件供应链安全。

在其核心,一个安全的软件供应链包括任何用于构建和交付一个应用程序给最终客户的东西。它建立在安全软件开发实践的基础上(例如,遵循OWASP前10名,SAST等)。任何安全供应链最佳实践的实施都需要建立关于构建过程的所有方面的证据,为所有步骤提供透明度,并创建机制以确保可靠的交付。

资料来源。

[1]https://www.propertycasualty360.com/2021/04/13/supply-chain-attacks-rose-42-in-q1/?slreturn=20210726153708

[2]https://portswigger.net/daily-swig/four-fold-increase-in-software-supply-chain-attacks-predicted-in-2021-report

[3]https://www.npr.org/2021/04/16/985439655/a-worst-nightmare-cyberattack-the-untold-story-of-the-solarwinds-hack

[4]https://www.zdnet.com/article/updated-kaseya-ransomware-attack-faq-what-we-know-now/

[5]https://portswigger.net/daily-swig/researcher-hacks-apple-microsoft-and-other-major-tech-companies-in-novel-supply-chain-attack

[6]https://www.whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/

[7]https://github.com/cncf/tag-security/raw/main/supply-chain-security/supply-chain-security-paper/CNCF_SSCP_v1.pdf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值