davidcollom/komodor-security-reporter
GitHub: davidcollom/komodor-security-reporter
一个 Kubernetes 原生的镜像漏洞监控工具,在运行中的工作负载与多种漏洞扫描器及 Komodor 平台之间搭建低噪音的安全事件桥梁。
Stars: 1 | Forks: 0
# Komodor 镜像漏洞监控器
一个 Kubernetes 原生监控器,用于检测容器镜像漏洞并将可操作的安全事件发布到 Komodor。
## 概述
此应用程序在运行中的 Kubernetes 工作负载、漏洞扫描器(Trivy、Trivy Operator 报告、Snyk、Wiz、Clair)和 Komodor 之间提供了一个安全、低噪音的桥梁。它能够:
- 监控 Kubernetes 工作负载(Deployments、StatefulSets、DaemonSets、Jobs、CronJobs)
- 从运行中的工作负载提取容器镜像
- 将可变标签解析为不可变摘要
- 使用可插拔的扫描器驱动程序扫描镜像以查找漏洞
- 将特定于扫描器的结果标准化为通用模型
- 将有意义的漏洞事件发布到 Komodor
- 对扫描结果进行去重,以避免告警疲劳
## 安全模型
该监控器在设计上具备强大的安全姿态:
- **无主机访问权限**:无 hostPath 挂载、运行时套接字或特权容器
- **无 Secret 访问权限**:不需要 Kubernetes API 权限来读取 Secrets
- **无模拟用户**:不模拟工作负载 ServiceAccounts
- **最小化 RBAC**:仅对工作负载元数据进行只读访问
- **受限制的容器**:以非 root 用户身份运行,具有只读文件系统并丢弃了部分 capabilities
有关完整的安全原则,请参见 [RFC](docs/rfc.md)。
## 快速开始
### 前置条件
- Kubernetes 1.24+
- 容器镜像扫描器(例如 Trivy)
- Komodor 账户和 API key
### 安装
```
# 使用 make
make install-tools
make build
# 或手动
go install ./cmd/komodor-security-reporter
```
### 配置
复制并自定义示例配置:
```
cp docs/example-config.yaml config.yaml
```
核心配置选项:
```
clusterName: prod-eks-01
# 要监控的 Namespaces
namespaces:
include:
- production
- platform
exclude:
- kube-system
# 要监控的 Workload kinds
workloads:
kinds:
- Deployment
- StatefulSet
# 要使用的 Scanners
scanners:
scanners:
- name: trivy
type: trivy
enabled: true
command:
binary: /usr/local/bin/trivy
timeout: 5m
# 发布策略
publishing:
mode: komodor
minimumSeverity: high
includeTopFindings: 5
publishCleanScans: false
dedupeTTL: 24h
komodor:
baseURL: https://app.komodor.io
```
### 本地运行
```
# 设置 Komodor API key(发布模式为 komodor 或 both 时需要)
export KOMODOR_API_KEY=your-api-key
# 使用配置运行
./bin/komodor-security-reporter -config config.yaml
# 启用 debug 日志记录
./bin/komodor-security-reporter -config config.yaml -log-level debug
```
## 开发
有关更多信息,请参见 [DEVELOPMENT.md](./docs/DEVELOPMENT.md)
## 架构
### 组件
1. **Kubernetes 工作负载监控器**:观察受支持的工作负载资源并检测镜像引用
2. **镜像提取器**:从 containers、initContainers 和 ephemeralContainers 中读取镜像
3. **摘要解析器**:使用 go-containerregistry 将镜像标签解析为不可变摘要
4. **扫描器注册表**:加载已配置的扫描器驱动程序并调用它们
5. **扫描器驱动程序**:扫描镜像并返回结构化结果(Trivy、Trivy Operator、Snyk、Wiz、Clair)
6. **发现标准化器**:将特定于扫描器的结果转换为通用模型
7. **策略评估器**:根据严重性和去重规则决定是否发布
8. **Komodor 发布器**:将标准化后的事件发布到 Komodor
9. **状态存储**:基于 ConfigMap 的去重状态
### 数据流
```
Kubernetes Workload
↓
Image Extractor
↓
Digest Resolver
↓
Scanner Registry
↓
Finding Normaliser
↓
Policy Evaluator
↓
Komodor Event Publisher
↓
State / Dedupe Store
```
## 测试
```
# 运行所有测试
make test
# 带 coverage 运行
make coverage
# 仅运行短测试(排除 integration tests)
make test-short
# 运行特定测试
go test -run TestFingerprint ./internal/policy
```
### 测试策略
- **单元测试**:所有核心逻辑组件(配置、扫描器、注册表、策略)
- **表驱动测试**:用于解析逻辑和策略评估
- **Mock/伪客户端**:用于 Kubernetes 和 Komodor 交互
- **集成测试**:可选,用于扫描器驱动程序(默认跳过)
## 部署
### Kubernetes 清单
有关完整的 Helm chart,请参见 `helm/` 目录。
最小的 ServiceAccount 和 RBAC:
```
apiVersion: v1
kind: ServiceAccount
metadata:
name: komodor-security-reporter
namespace: security
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: komodor-security-reporter
rules:
- apiGroups: [""]
resources: [namespaces]
verbs: [get, list, watch]
- apiGroups: [apps]
resources: [deployments, statefulsets, daemonsets]
verbs: [get, list, watch]
- apiGroups: [batch]
resources: [jobs, cronjobs]
verbs: [get, list, watch]
# For ConfigMap-backed state store
- apiGroups: [""]
resources: [configmaps]
verbs: [get, list, create, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: komodor-security-reporter
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: komodor-security-reporter
subjects:
- kind: ServiceAccount
name: komodor-security-reporter
namespace: security
```
### Pod 安全
```
spec:
securityContext:
runAsNonRoot: true
runAsUser: 65534
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
containers:
- name: watcher
image: komodor-security-reporter:latest
imagePullPolicy: IfNotPresent
env:
- name: KOMODOR_API_KEY
valueFrom:
secretKeyRef:
name: komodor-credentials
key: api-key
ports:
- name: metrics
containerPort: 8080
volumeMounts:
- name: config
mountPath: /etc/komodor-security-reporter
readOnly: true
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /var/cache/komodor-security-reporter
volumes:
- name: config
configMap:
name: komodor-security-reporter
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
```
## 指标
Prometheus 指标在 `:8080/metrics` 上公开:
- `image_vuln_watcher_images_observed_total` - 观察到的镜像总数
- `image_vuln_watcher_images_resolved_total` - 解析为摘要的镜像总数
- `image_vuln_watcher_image_resolution_errors_total` - 解析失败数
- `image_vuln_watcher_scans_total` - 执行的扫描总数
- `image_vuln_watcher_scan_errors_total` - 扫描失败数
- `image_vuln_watcher_scan_duration_seconds` - 扫描耗时直方图
- `image_vuln_watcher_events_published_total` - 已发布的事件数
- `image_vuln_watcher_event_publish_errors_total` - 发布失败数
- `image_vuln_watcher_dedupe_hits_total` - 去重的事件数
## 调试 Kubernetes 事件
当使用 `--publish-mode=events` 或 `--publish-mode=both` 运行时,报告器会在受影响的工作负载上创建原生的 Kubernetes `Warning` 事件。你可以使用 `kubectl` 检查这些事件:
```
# 列出所有 namespaces 中的所有 VulnerabilityScan 事件
kubectl get events -A --field-selector reason=VulnerabilityScan
# 过滤到特定的 namespace
kubectl get events -n --field-selector reason=VulnerabilityScan
# 实时监控 events
kubectl get events -A --field-selector reason=VulnerabilityScan -w
# 显示特定 workload 的完整 event 详情
kubectl describe deployment/ -n | grep -A5 VulnerabilityScan
# 按 reporting component 过滤
kubectl get events -A \
--field-selector reportingComponent=komodor-security-reporter
```
事件使用 `reason=VulnerabilityScan` 且 `type=Warning`(对于无漏洞的扫描则为 `Normal`)。`MESSAGE` 列包含漏洞摘要,例如:
```
summary="critical=3 high=21 medium=16 low=1 total=49" scanner=trivy image=... findings=49 (critical=3 high=21 medium=16 low=1)
```
## 日志记录
结构化日志使用带有上下文字段的 JSON 输出:
```
{"level":"info","msg":"loaded configuration","cluster":"prod-eks-01","time":"2024-01-15T10:30:45Z"}
{"level":"warn","msg":"failed to resolve image digest","image":"ghcr.io/acme/app:1.0","error":"404 not found"}
```
日志级别:`debug`、`info`(默认)、`warn`、`error`
## 可观测性
### 健康检查
`GET /healthz` - 如果服务健康则返回 200 OK
### 指标
`GET /metrics` - Prometheus 格式的指标
### 日志
所有事件都使用以下字段构建结构:
- `cluster` - 集群名称
- `namespace` - 工作负载命名空间
- `workloadKind` - 工作负载类型(Deployment 等)
- `workloadName` - 工作负载名称
- `container` - 容器名称
- `image` - 镜像引用
- `digest` - 镜像摘要
- `scanner` - 扫描器名称
## 发布
### 本地构建发布
```
# 构建 snapshot(开发)
make release-snapshot
# 创建 release(需要 git tag)
# 1. Tag release:git tag v0.1.0
# 2. 运行 release:
make release
```
发布过程:
1. 为 linux/amd64、linux/arm64、darwin/amd64、darwin/arm64 构建二进制文件
2. 创建归档文件和校验和
3. 构建并推送 Docker 镜像(需要 Docker 凭据)
4. 创建包含二进制文件的 GitHub release
5. 根据 commits 生成 changelog
### Docker 镜像
镜像发布至:`ghcr.io/davidcollom/komodor-security-reporter`
标签:
- `vX.Y.Z` - 特定版本
- `latest` - 最新版本
## 配置参考
有关完整的配置选项,请参见 [docs/example-config.yaml](docs/example-config.yaml)。
## 架构决策记录
有关设计决策,请参见 [docs/rfc.md](docs/rfc.md#decision-record):
- v1 版本无 CRDs
- 无 Kubernetes Secret 读取 RBAC 权限
- 不进行模拟用户
- 无主机级别访问权限
## 许可证
Apache License 2.0
## 支持
如有问题、疑问或建议,请提交 GitHub issue。
标签:DevOps工具, DevSecOps, DNS 解析, EVTX分析, Go语言, GPT, k8s, K8s监控, Komodor, RBAC, Snyk, StruQ, Web截图, Wiz, 上游代理, 云原生应用保护, 子域名突变, 安全告警, 容器安全, 微服务安全, 无侵入式安全, 日志审计, 最小权限原则, 漏洞管理, 程序破解, 自定义请求头, 请求拦截