statnett/image-scanner-operator
GitHub: statnett/image-scanner-operator
Kubernetes Operator 用于检测运行中容器镜像的漏洞,弥补流水线扫描无法覆盖已上线工作负载的盲区。
Stars: 33 | Forks: 10
# Image Scanner Operator
[][conventional-commits]
[][report-card]
[][CodeQL]
Image Scanner 是一个支持检测运行中容器镜像漏洞的 Kubernetes Operator。
Kubernetes 集群运行的容器源自来源多样的容器镜像。
有些镜像是为内部应用定制的,而另一些则是从内部/外部 registry 拉取的。
在容器镜像构建流水线中扫描镜像被视为最佳实践,以便向开发者提供关于潜在漏洞的早期反馈。
虽然这很好,但这还不够:
软件漏洞通常在软件可供使用后才被检测到,而一些应用通常会在其运行时环境中“仅仅运行”——很少或根本没有维护。
而且有些用户可能根本不使用流水线,或者使用未启用镜像扫描的流水线。
在包含漏洞的容器镜像上运行应用程序_可能_代表一种不可接受的威胁。
为了解决这个问题,我们需要**一种识别运行中容器镜像漏洞的机制**。
然后,开发者、系统管理员、平台管理员和安全官员可以使用此机制
在检测到漏洞时采取行动。
行动例如可以是:
- 升级到易受攻击软件组件的修补版本
- 得出漏洞不相关的结论
- 得出漏洞代表可接受风险的结论
- 关闭应用程序
似乎有很多公司/社区提供类似的软件。此 operator 的一些关键特性是:
- **可配置为扫描任何 [Kubernetes Workload](https://kubernetes.io/docs/concepts/workloads/) 的容器镜像**,
包括自定义资源。唯一的要求是资源必须
[拥有](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/)
Pod——无论是直接还是间接。
- **容器镜像基于从 [Container Runtime Interface (CRI)](https://kubernetes.io/docs/concepts/architecture/cri/) 获取的不可变镜像 sha256 digest 进行扫描**,
而不是基于可能可变的镜像 tag。
- 为避免不必要的镜像拉取,镜像扫描 workload 最好调度在与待扫描 workload 相同的节点上。
- 由于待扫描的镜像应该已经存在于节点容器 registry 中,**镜像扫描 workload 不必为私有镜像处理镜像拉取 secret**,利用了一个 [Kubernetes "bug"](https://github.com/kubernetes/kubernetes/issues/18787)。
## Description
// TODO(user): 关于您的项目和概述的深入段落
### Custom resources
Image Scanner operator 目前定义了面向用户的单一自定义资源定义 (CRD),即 [ContainerImageScan][CIS-CRD] (CIS),它代表了 workload 容器镜像运行时镜像扫描的 Kubernetes API。
有关 CIS 资源的(简化)示例,请参见 [stas_v1alpha1_containerimagescan.yaml][CIS-example]。
CIS 资源 `.spec` 指定要扫描的容器镜像和一些额外的 workload 元数据,镜像扫描结果的摘要由 `ContainerImageScan` controller 在 `.status` 中添加/更新。
检测到的漏洞的详细报告发布到由 CIS 拥有的 [OpenReports](https://openreports.io/) `Report` 资源中。
有关 Image Scanner operator 管理的 `Report` 资源示例,请参见 [v1alpha1_report.yaml][Report-example]。
标准用户不应编辑 CIS 资源,因为 `Workload` controller 将从运行中的 pod 创建 CIS 资源。并且当拥有 pod 消失时,标准 Kubernetes 垃圾收集器会删除过时的 CIS 资源。
用户可以通过向 pod 添加 annotation 来影响镜像扫描过程。
annotation 集合目前有限,但未来可能会添加更多:
| Pod annotation key | Default value | Description |
|--------------------------------------------|:--------------|:----------------------------------------------------------------------------------------------------------------------|
| `image-scanner.statnett.no/ignore-unfixed` | `"false"` | If set to `"true"`, the Image Scanner will ignore any detected vulnerability that can't be fix by updating package(s) |
### Supported features
- Namespaced 容器镜像扫描 API (custom resource): `ContainerImageScan` (CIS)
- CIS 资源包含已检测漏洞的详细信息和摘要
- 用户可以识别已扫描容器镜像的拥有/控制资源 (workload)
- 所有容器镜像都会定期重新扫描,间隔可配置
- 提供 CIS 的漏洞摘要指标以启用仪表板/警报
- 任何有权访问 namespace 的用户都被允许_查看_ CIS
- Cluster-scoped operator,在配置的 namespace 中运行,具有应扫描的 namespace 的包含/阻止列表
- 通过配置支持任何类型的 workload(也包括 CRD)
- 扫描来自私有/认证镜像 registry 的 workload 镜像
### Future improvements
- 向利益相关者推送反馈
- 允许用户忽略/抑制漏洞
- 根据检测到的漏洞执行操作
### Eschewed Features
- 生成漏洞详情指标
- 历史容器镜像扫描
- Helm chart 安装
## Getting Started
您需要一个 Kubernetes 集群来运行 Image Scanner。
您可以使用 [KIND](https://sigs.k8s.io/kind) 或 [k3s](https://k3s.io/)
来获取用于测试的本地集群。
我们目前仅支持使用 [Kustomize](https://kustomize.io/) 进行安装,
无论是作为独立工具,
使用 `kubectl` 最新版本中的 kustomize (`-k`) 功能,
还是任何支持 Kustomize 的 GitOps 工具。
### Prerequisites
在安装 Image Scanner operator 之前,OpenReports CRD 必须存在于集群中。
如果您正在使用 [Kyverno](https://kyverno.io/),OpenReports CRD 可能已经安装。从 Kyverno 1.15 版本(Helm chart 3.5)开始,有一个选择性加入 (opt-in) 选项可以让 Kyverno 以 OpenReports 格式生成报告。要启用该选项,
请设置 Kyverno Helm chart 值 `openreports.enable=true`,这将确保所需的 CRD 由 Kyverno Helm chart 安装。
如果您没有使用 Kyverno,可以使用上游 [OpenReports Helm chart](https://github.com/openreports/reports-api/pkgs/container/charts%2Fopenreports) 安装 OpenReports CRD。
```
helm install oci://ghcr.io/openreports/charts/openreports
```
### Install
由于您可能希望调整默认配置(和/或拥有多个集群),我们建议您首先使用 Image Scanner 默认 kustomization 作为
[remote directory](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/remoteBuild.md#remote-directories)
base 来创建 kustomize overlay。您最初的 kustomization.yaml 可以很简单:
```
resources:
- https://github.com/statnett/image-scanner-operator?ref=v0.16.13
```
如果您有多个集群,则应为每个集群创建一个
[variant](https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#variant)
overlay。
要将 operator 安装(或更新)到您的集群中,请运行:
```
kubectl apply --server-side -k
```
### Configure
Image Scanner operator 高度可配置,并支持带有相应环境变量的众多 flag。要概览所有可配置的内容,最简单的方法是使用 CLI:
```
docker run ghcr.io/statnett/image-scanner-operator --help
```
您也可以使用环境变量进行配置,但 flag 优先于相应的环境变量。
环境变量名称可以通过大写并将 `-` 分隔符替换为 `_` 从 flag 推断出来。
由于我们使用 kustomize 安装 operator,最简单的方法是
使用 [configMapGenerator](https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/configmapgenerator/)
从默认 Image Scanner 配置中的 ConfigMap 定制提供的环境变量。
```
configMapGenerator:
- name: image-scanner-config
behavior: merge
literals:
- CIS_METRICS_LABELS=app.kubernetes.io/name
- SCAN_INTERVAL=24h
```
此示例将覆盖默认配置为:
- 添加从 `app.kubernetes.io/name` Pod label 获取值的 metric label
- 以 24 小时的间隔重新扫描 workload 镜像
#### Configure Trivy scan jobs
workload 容器镜像通过调度运行在扫描目标容器镜像上的 Kubernetes _Job_ 进行扫描。使用 job 容器内的
[`trivy filesystem`](https://aquasecurity.github.io/trivy/latest/docs/references/configuration/cli/trivy_filesystem/)
命令扫描镜像。
`trivy filesystem` 扫描命令可以通过修改
`trivy-job-config` _ConfigMap_ 进行自定义。_ConfigMap_ 中的所有条目都作为带有 `TRIVY_` 前缀的环境变量挂载——这将允许 Trivy 选取它们。示例:
```
- name: trivy-job-config
namespace: image-scanner
behavior: merge
literals:
- DB_REPOSITORY=/aquasecurity/trivy-db
- JAVA_DB_REPOSITORY=/aquasecurity/trivy-java-db
- OFFLINE_SCAN=true # enabling offline mode for air-gapped environments
```
### Upgrade
在这个早期阶段,我们可能会引入破坏性变更。但当我们这样做时,
破坏性变更应在 changelog 和 release notes 中突出显示。
我们也可能对 CRD 进行破坏性更改,而不增加转换 webhook 的复杂性。因此,如果您在升级到更新版本时遇到任何问题,请首先尝试重新安装 operator。
### Uninstall
要卸载 operator,只需使用 `kubectl` 删除 [安装](#install) operator 时 overlay 生成的所有资源:
```
kubectl delete -k --ignore-not-found=true
```
### How it works
该项目旨在遵循 Kubernetes
[Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)。
它使用
[Controllers](https://kubernetes.io/docs/concepts/architecture/controller/)
,它提供一个 reconcile 函数,负责同步资源
直到达到所需状态。
Image Scanner 由三个 controller 组成,它们协调
运行中容器镜像的扫描,如下图所示。
容器镜像扫描 Kubernetes API 由 `ContainerImageScan` 自定义资源实体化,
在其 status 中提供最终一致的镜像扫描摘要。
容器镜像的实际漏洞扫描和漏洞数据库由 operator 的外部服务提供。
使用一个简单的 `Pod`(带有单个容器)作为示例:
1. 当 `Pod` status 中存在不可变镜像引用时,创建一个 `ContainerImageScan`。
2. 从 `ContainerImageScan` spec 中的不可变镜像引用创建一个扫描 `Job`。
3. 当扫描 `Job` 完成后,从扫描 `Job` 的 pod log 读取扫描结果,
并更新 `ContainerImageScan` status。创建/更新包含已检测漏洞详情的 `Report` 资源。
4. 当 `Pod` 被删除时,`ContainerImageScan` 和 `Report` 被垃圾回收。
)

## License
Licensed under the [MIT License](LICENSE).
标签:Claude, CVE检测, DevSecOps, EVTX分析, Go, K8s工具, Operator, Ruby工具, Web截图, 上游代理, 子域名突变, 安全合规, 容器安全, 日志审计, 活动识别, 网络代理, 镜像扫描, 镜像漏洞