作者:Dan Lorenc 和 Priya Wadhwa |文章最初张贴在security.googleblog.com[1]
如果你最近一直关注新闻,你可能已经注意到,软件供应链攻击正在迅速成为一个大问题。无论你是试图防止这些攻击、响应正在进行的攻击,还是从正在进行的攻击中恢复,你都知道了解 CI/CD 流水线中发生的事情是至关重要的。
幸运的是,Kubernetes 原生的Tekton[2]项目——一个用于创建 CI/CD 系统的开源框架——从第一天起就考虑到了安全性,而新的Tekton Chains[3]项目将帮助它达到一个新的水平。Tekton Chains 安全地捕获 CI/CD 流水线执行的元数据。在 Tekton 的早期阶段,我们做出了两个非常重要的设计决策,这使得供应链的安全性变得很容易:声明性的流水线定义和显式的状态转换。下一节将解释这些在实践中意味着什么,以及它们如何使构建安全交付流水线变得容易。
就像高中物理课上的所有东西一样,CI/CD 流水线可以被建模为一系列盒子。每个框都有一些输入,一些输出,以及中间发生的一些步骤。即使你有一个大型复杂的 bash 脚本来获取依赖项、构建程序、运行测试、下载互联网并部署到生产环境中,你也可以绘制方框和箭头来表示此流。盒子可能很大,但你可以做到。
从最初的白板草图开始,Tekton 中的 Pipeline 和 Task CRD 被设计为允许用户在粒度级别上定义流水线的每一步。这些类型包括对强制声明的输入、输出和构建环境的支持。这意味着你可以准确地跟踪构建过程中使用了什么资源,在构建过程中使用了什么工具,以及最终产生了什么工件。通过将一个大型的整体流水线分解为一系列较小的、可重用的步骤,你可以增加整个系统的可见性。这使你更容易理解供应链攻击的暴露情况,在问题发生时检测问题,并在问题发生后恢复。
在定义流水线之后,有几种方法来编排它:水平触发(level-triggered)和边缘触发(edge-triggered)。与 Kubernetes 的大多数生态系统一样,Tekton 的设计也是基于水平触发方式。这意味着步骤是由中央编排器显式执行的,它运行一个任务,等待完成,然后决定下一步做什么。在基于边缘触发的系统中,流水线定义将被转换为一组事件和侦听器。每个步骤在完成时触发事件,然后这些事件由运行下一组步骤的侦听器拾取。
基于事件或边缘触发的系统很容易理解,但在规模上很难管理。当工件流经整个系统时,它们也使跟踪工件变得更加困难。流水线中的每一步都只知道它之前的一步;没有任何步骤负责跟踪整个执行。当你试图了解交付流水线的安全状况时,这可能会产生问题。
Tekton 的设计思想与此相反——水平触发。Tekton 不是一个用胶带和晒衣夹绑在一起的 Rube-Goldberg 机器,更像是一条明确的装配线。像 Tekton 这样的关卡触发系统通过中央协调器从一种状态移动到另一种状态。它们需要更明确的预先设计,但是它们更容易观察和推理。使用 Tekton 这样系统的供应链更安全。
那么,这两个设计决策如何结合起来使供应链安全变得更容易呢?欢迎来到 Tekton Chains。
通过观察 Task 或 Pipeline 的执行,并仔细注意过程中的输入、输出和步骤,我们可以稍后更容易地跟踪发生了什么以及原因。这个“观察者”可以在单独的信任域中运行,并在存储所有捕获的元数据时对其进行加密签名,从而留下一个防篡改的活动分类账。这种技术被称为“可验证构建”。这种安全生成的元数据可以以多种方式使用,从审计日志记录到从安全漏洞恢复到部署前策略实施。
你可以将 Chains 安装到任何启用 Tekton 的集群中,并将其配置为为你的构建生成此加密签名的供应链元数据。Chains 支持 PGP、x509 和 Cloud KMS 等可插接签名系统。有效载荷可以以几种不同的行业标准格式生成,比如 RedHat Simple-Signing 和 In-Toto Provenance 规范。完整的文档可以在这里[4]找到,但是你可以像这样快速开始:
对于本教程,你将需要访问一个 GKE Kubernetes 集群和一个带有推送凭证的 GCR 注册表。集群应该已经安装了 Tekton pipeline。
将 Tekton Chains 安装到集群中:
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
接下来,你将为 Tekton Chains 控制器设置注册中心身份验证,这样它就可以将 OCI 镜像签名推到你的注册中心。要设置身份验证,你将创建一个服务帐户并下载凭据:
$ export PROJECT_ID=<GCP Project ID>
$ gcloud iam service-accounts create tekton-chains
$ gcloud iam service-accounts keys create credentials.json --iam-account=tekton-chains@${PROJECT_ID}.iam.gserviceaccount.com
现在,从你的凭证文件中创建一个 Kubernetes Secret,这样 Chains 控制器就可以访问它:
$ kubectl create secret docker-registry registry-credentials \
--docker-server=gcr.io \
--docker-username=_json_key \
--docker-email=tekton@chains.com \
--docker-password="$(cat credentials.json)" \
-n tekton-chains
$ kubectl patch serviceaccount tekton-chains-controller \
-p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n tekton-chains
我们可以使用cosign[5]来生成一个作为 Kubernetes 秘密的密钥对,Chains 控制器将使用它来进行签名。Cosign 会要求输入密码,密码会保存在秘密文件中:
$ cosign generate-key-pair -k8s tekton-chains/signing-secrets
接下来,你需要为 kaniko 任务设置 GCR 注册表的身份验证,作为另一个 Kubernetes Secret。
$ export CREDENTIALS_SECRET=kaniko-credentials
$ kubectl create secret generic $CREDENTIALS_SECRET --from-file credentials.json
现在,我们将创建一个 kaniko-chains 任务,它将构建一个容器镜像并将其推送到注册表中。Tekton Chains 将识别已构建的景象,并自动对其进行签名。
$ kubectl apply -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/kaniko/gcp/kaniko.yaml
$ cat <<EOF | kubectl apply -f -
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: kaniko-run
spec:
taskRef:
name: kaniko-gcp
params:
- name: IMAGE
value: gcr.io/${PROJECT_ID}/kaniko-chains
workspaces:
- name: source
emptyDir: {}
- name: credentials
secret:
secretName: ${CREDENTIALS_SECRET}
EOF
等待 TaskRun 完成,并给 Tekton Chains 控制器几秒钟时间来对镜像进行签名并存储签名。你应该能够用 cosign 和你的公钥来验证签名:
$ cosign verify -key cosign.pub gcr.io/${PROJECT_ID}/kaniko-chains
恭喜你!你已经成功地使用 Tekton Chains 和 cosign 对 OCI 镜像进行了签名和验证。
在链内,我们将改进与其他供应链安全项目的集成。这包括通过与Sigstore[6]和In-Toto[7]项目集成来支持 Binary Transparency 和 Verifiable Builds。我们还将在 TektonCD 目录中改进并提供一组设计良好、高度安全的任务和流水线定义。
在Tekton Pipelines[8]中,我们计划完成TEP-0025[9](Hermekton),以支持密封构建执行。如果你现在想玩一玩,hermekton 可以在实验模式中作为alpha 功能[10]运行。当启用 hermekton 时,构建运行在没有网络连接的锁定环境中。Hermetic 构建保证了所有输入都提前明确声明,从而提供了一个更可审计的供应链。密封性构建和 Chains 对齐得很好,因为密封性构建属性包含在 Chains 捕获的完整构建来源中。Chains 可以生成并验证指定构建的哪个部分具有网络访问权限的元数据。
这意味着可以准确地定义哪些构建工具可以访问网络,哪些不能。此元数据可以在构建时在策略中使用(禁止具有安全漏洞的编译器),也可以在部署时被策略引擎存储和使用(只允许代码审查和验证构建的容器运行)。
我们认为,供应链安全必须是内在的,并且是默认的。没有任务编排器可以保证完美的供应链安全,但 TektonCD 在设计时考虑了独特的功能,使它更容易做正确的事情。我们总是在寻找关于设计、目标和需求的反馈。你可以在GitHub[11]或#chains[12] Slack 频道上联系。
[1]
security.googleblog.com: https://security.googleblog.com/2021/06/verifiable-supply-chain-metadata-for.html
[2]
Tekton: http://tekton.dev/
[3]
Tekton Chains: https://github.com/tektoncd/chains
[4]
这里: https://github.com/tektoncd/chains
[5]
cosign: https://github.com/sigstore/cosign
[6]
Sigstore: https://sigstore.dev/
[7]
In-Toto: https://in-toto.io/
[8]
Tekton Pipelines: https://github.com/tektoncd/pipeline
[9]
TEP-0025: https://github.com/tektoncd/community/blob/main/teps/0025-hermekton.md
[10]
alpha 功能: https://github.com/tektoncd/pipeline/blob/main/docs/hermetic.md
[11]
GitHub: https://github.com/tektoncd/chains
[12]
#chains: https://tektoncd.slack.com/messages/chains
点击【阅读原文】阅读网站原文。
Linux基金会诚意邀您参与:
文章转载自LFAPAC。点击这里阅读原文了解更多。