作者:Karan Kumar (@karanibm6[1])
引言
在现代软件开发中,容器已成为开发者的重要工具。它们为应用程序提供了一致的运行环境,使得在不同平台上开发、测试和部署软件变得更加容易。然而,容器也并非没有安全漏洞。因此,对容器镜像进行漏洞扫描变得至关重要。在这篇博客中,我们将讨论如何在使用 Shipwright[2] 构建镜像时进行漏洞扫描。
在深入这个功能之前,先解释一下什么是 Shipwright,以及为什么漏洞扫描很重要。
什么是 Shipwright
Shipwright 是一个开源框架,旨在促进在 Kubernetes 环境中直接构建容器镜像。它通过提供原生 Kubernetes 解决方案来简化从源代码创建容器镜像的开发和部署过程。Shipwright 支持多种构建策略和工具,如 Kaniko、Paketo Buildpacks、Ko、Buildkit 和 Buildah,提供了灵活性和可扩展性,以满足不同应用的需求。这个原生解决方案确保容器镜像的高效和安全构建,充分利用 Kubernetes 生态系统的优势。
Shipwright 由四个核心组件组成:
Build:定义要构建的源代码以及生成的容器镜像的发布位置(什么和在哪里?)。 BuildRun:定义何时触发构建机制,告诉 Kubernetes 集群何时构建应用程序(何时?)。 BuildStrategy 和 ClusterBuildStrategy:定义应用程序的组装方式以及使用哪个构建工具(如何构建?)。
你可以通过访问相关链接[3]了解更多信息。
为什么漏洞扫描很重要?
对容器镜像进行漏洞扫描是检查镜像是否存在已知安全漏洞。通常使用自动化工具将镜像内容与已知漏洞数据库进行比较。漏洞扫描的重要原因包括:
安全性:容器通常包含第三方库和依赖项,这些可能存在已知漏洞。如果这些漏洞被利用,可能导致数据泄露、未经授权访问等安全事件。 合规性:许多行业有规定,要求定期进行安全评估,包括漏洞扫描。确保容器镜像没有已知漏洞有助于满足这些合规标准。 稳定性:漏洞还可能影响应用程序的稳定性和性能。通过及早识别和修复这些问题,可以维护软件的可靠性。
目前有许多流行的工具可用于容器镜像的漏洞扫描,如 Clair、Trivy、Aqua Security 和 Snyk。
在 Shipwright 中,我们使用 Trivy 进行漏洞扫描,选择这个工具的理由可以在 SHIP-0033[4] 中找到。
Shipwright 中的漏洞扫描
在介绍如何工作之前,让我们了解 Shipwright 在容器构建的漏洞扫描方面提供的功能:
spec:
output:
vulnerabilityScan:
enabled: true
failOnFinding: true #image won't be push to registry if set to true
ignore:
issues:
- CVE-2022-12345 #specify list of cve to be ignored
severity: Low | Medium | High | Critical
unfixed: true #ignores the unfixed vulnerabilities
配置选项
vulnerabilityScan.enabled:指定是否对镜像运行漏洞扫描。支持的值为 true 和 false。 vulnerabilityScan.failOnFinding:指示如果漏洞扫描结果中有漏洞,是否让构建失败。支持的值为 true 和 false。此字段为可选,默认为 false。 vulnerabilityScan.ignore.issues:引用在漏洞扫描中要忽略的安全问题。 vulnerabilityScan.ignore.severity:表示要忽略的安全问题的严重性级别,有效值为: low:排除低严重性漏洞,仅显示中、高和关键漏洞。 medium:排除低和中严重性漏洞,仅显示高和关键漏洞。 high:排除低、中和高严重性漏洞,仅显示关键漏洞。 vulnerabilityScan.ignore.unfixed:指示忽略没有修复的漏洞。支持的类型为 true 和 false。
让我们深入了解
现在,让我们看看使用 Shipwright 进行容器镜像漏洞扫描的实际操作。如果你想在 kind 集群中尝试,请按照本节[5]的步骤操作,直到创建推送密钥。接下来,创建一个启用漏洞扫描的构建对象,将 <REGISTRY_ORG>
替换为你的推送密钥所能访问的注册表用户名:
REGISTRY_ORG=<your_registry_org>
cat <<EOF | kubectl apply -f -
apiVersion: shipwright.io/v1beta1
kind: Build
metadata:
name: buildah-golang-build
spec:
source:
type: Git
git:
url: https://github.com/shipwright-io/sample-go
contextDir: docker-build
strategy:
name: buildah-shipwright-managed-push
kind: ClusterBuildStrategy
paramValues:
- name: dockerfile
value: Dockerfile
output:
image: docker.io/${REGISTRY_ORG}/sample-golang:latest
pushSecret: push-secret
vulnerabilityScan:
enabled: true
failOnFinding: true # if set to true, then the image won't be pushed to the registry
EOF
要查看刚创建的 Build:
$ kubectl get builds
NAME REGISTERED REASON BUILDSTRATEGYKIND BUILDSTRATEGYNAME CREATIONTIME
buildah-golang-build True Succeeded ClusterBuildStrategy buildah-shipwright-managed-push 72s
现在提交你的 BuildRun:
cat <<EOF | kubectl create -f -
apiVersion: shipwright.io/v1beta1
kind: BuildRun
metadata:
generateName: buildah-golang-buildrun-
spec:
build:
name: buildah-golang-build
EOF
等待 BuildRun 完成后,你可以按如下方式查看它:
$ kubectl get buildruns
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
buildah-golang-buildrun-s9gsh False VulnerabilitiesFound 2m54s 98s
在这里,你可以看到构建运行因“VulnerabilitiesFound”而失败,由于 failOnFinding
选项设置为 true,它将不会将镜像推送到注册表。
你可以在构建运行的 .status.output
路径下找到漏洞列表。
apiVersion: shipwright.io/v1beta1
kind: BuildRun
metadata:
creationTimestamp: "2024-07-08T08:03:18Z"
generateName: buildah-golang-buildrun-
generation: 1
labels:
build.shipwright.io/generation: "1"
build.shipwright.io/name: buildah-golang-build
name: buildah-golang-buildrun-s9gsh
namespace: default
resourceVersion: "19926"
uid: f3c558e9-e027-4f59-9fdc-438a31c6de11
spec:
build:
name: buildah-golang-build
status:
buildSpec:
output:
image: docker.io/karanjmu92/sample-golang:latest
pushSecret: push-secret
vulnerabilityScan:
enabled: true
failOnFinding: true
paramValues:
- name: dockerfile
value: Dockerfile
source:
contextDir: docker-build
git:
url: https://github.com/shipwright-io/sample-go
type: Git
strategy:
kind: ClusterBuildStrategy
name: buildah-shipwright-managed-push
completionTime: "2024-07-08T08:04:34Z"
conditions:
- lastTransitionTime: "2024-07-08T08:04:34Z"
message: Vulnerabilities have been found in the image which can be seen in the
buildrun status. For detailed information,see kubectl --namespace default logs
buildah-golang-buildrun-s9gsh-w488m-pod --container=step-image-processing
reason: VulnerabilitiesFound
status: "False"
type: Succeeded
failureDetails:
location:
container: step-image-processing
pod: buildah-golang-buildrun-s9gsh-w488m-pod
output:
vulnerabilities:
- id: CVE-2023-24538
severity: critical
- id: CVE-2023-24540
severity: critical
.
.
.
- id: CVE-2024-24791
severity: medium
source:
git:
branchName: main
commitAuthor: OpenShift Merge Robot
commitSha: 96afb4108fba22e91f42168d8babb5562ac8e5bb
timestamp: "2023-08-10T15:24:45Z"
startTime: "2024-07-08T08:03:18Z"
taskRunName: buildah-golang-buildrun-s9gsh-w488m
总结
Shipwright 为在 Kubernetes 环境中构建容器镜像提供了一种强大而灵活的解决方案。通过将漏洞扫描直接集成到构建过程中,Shipwright 确保容器镜像安全且符合行业标准,接近供应链安全最佳实践。
@karanibm6: https://github.com/karanibm6
[2]Shipwright: https://shipwright.io/
[3]链接: https://shipwright.io/blog/2020/11/30/introducing-shipwright-part-2/#the-build-apis
[4]SHIP-0033: https://github.com/shipwright-io/community/blob/main/ships/0033-build-output-vulnerability-scanning.md
[5]本节: https://github.com/shipwright-io/build?tab=readme-ov-file#try-it
点击【阅读原文】阅读网站原文。
联系Linux Foundation APAC
Linux基金会是非营利性组织,是技术生态系统的重要组成部分。
Linux基金会通过提供财务和智力资源、基础设施、服务、活动以及培训来支持创建永续开源生态系统。在共享技术的创建中,Linux基金会及其项目通过共同努力形成了非凡成功的投资。请关注LFAPAC(Linux Foundation APAC)微信公众号。