Skip to content

租户 Helm Chart 审计

审计方法论:本文档记录的是基于 chart 检查得出的预期分类。发布前验证中必须执行实际的 helm template 运行,并将结果与分类进行 diff 对比。在真实渲染结果中发现的、此处未列出的任何对象都将成为一道审查门禁。

审计范围

待审计的 chart:

上游上游来源目标版本
Wazuhwazuh/wazuh-kubernetes Helm chart(社区版)或官方 OCI chart支持单 manager HA 的最新稳定 4.x
TheHiveStrangeBee/thehive4 Helm chart 或社区版5.x
CortexTheHive-Project/Cortex Helm chart 或社区版3.x
MISP推迟到后续版本

对于每个 chart,我们将其 manifest 模板(如有需要则附带补丁)以子 chart 依赖的形式纳入 charts/soctalk-tenant/:版本锁定是严格的。Chart.yaml 采用精确 semver,并在可用时(OCI)附带 digest。

分类规则

对于每个渲染出的对象,按如下方式分类:

  • NS-OK:位于 tenant-<slug> 内部的命名空间级对象。安全、预期之内。
  • CLUSTER-PREREQ:集群级对象,必须由 soctalk-system chart 一次性安装,或作为 MSSP 集群管理员的职责记录在案。租户 chart 不得为每个租户重复安装这些对象。
  • FORBIDDEN:即使上游声明了,我们也拒绝在租户 chart 中允许的对象类型或能力(例如授予 Wazuh 特权访问的集群级 ClusterRoleBinding)。必须通过补丁移除。
  • PATCH:保留该对象但对其进行修改(例如去掉 hostPath 卷、移除特权 securityContext、降低默认资源请求)。

各上游 chart 的预期分类

Wazuh

Wazuh chart 通常渲染出:

对象预期分类备注
Deployment / StatefulSet(manager、indexer、dashboard)NS-OK核心栈 Pod
Service(manager API、indexer、dashboard、agent ingress 1514/1515)NS-OK
ConfigMap(ossec.conf、indexer.yml、dashboard.yml)NS-OK
Secret(管理员密码、双向 TLS 证书)NS-OK在预置时按租户注入
PersistentVolumeClaim(indexer 数据、manager 数据)NS-OK大小通过租户 values 设置
ServiceAccountNS-OK每租户一个 SA
Role + RoleBinding(如使用领导者选举)NS-OK仅限命名空间级
NetworkPolicy(chart 提供)PATCH替换为 SocTalk 渲染的 NP 以保持一致的姿态;不允许上游默认值覆盖 default-deny
StorageClass 引用CLUSTER-PREREQMSSP 必须提供动态供给器;storageClassName 是一个 values 输入项
IngressPATCH 或禁用Wazuh 在 1514 上的 agent 协议不是标准 TLS,因此 HTTP/HTTPS Ingress 并不适用。移除所有 Ingress 资源。对于 agent-ingress Service,chart 应渲染与 tenant.wazuhIngress.mode 相匹配的变体:为每租户 LB IP 渲染 LoadBalancer Service(默认),或在安装使用集群内 HAProxy 回退方案时渲染 ClusterIP Service。参见 Wazuh Ingress
PodSecurityPolicy / SecurityContextConstraints存在时为 CLUSTER-PREREQ;否则为 forbiddenPSP 已弃用;如存在则移除。OpenShift SCC 不在本版本范围内
CustomResourceDefinition在租户 chart 中 FORBIDDEN如果 chart 试图安装 CRD,则移至 soctalk-system chart 或作为前置条件记录在案
ClusterRole / ClusterRoleBinding在租户 chart 中 FORBIDDEN绝不从租户命名空间安装集群级 RBAC
特权 / host-network / hostPath PodFORBIDDEN;通过补丁移除Wazuh manager 在标准运行中不需要这些;indexer 同样不需要。如果某个子 chart 需要 hostPath 存放日志,则打补丁改为 emptyDir + PVC
PodDisruptionBudgetNS-OK可选;取决于 Wazuh HA 模式。单 manager 拓扑可跳过

预期补丁

  1. 从渲染输出中移除任何 ClusterRole/ClusterRoleBinding
  2. 移除任何集群级资源(ValidatingWebhookConfiguration 等)。
  3. 渲染 agent-ingress Service 以匹配 tenant.wazuhIngress.mode(为每租户 LB IP 使用 LoadBalancer,为集群内 HAProxy 回退方案使用 ClusterIP)。
  4. 移除 Ingress 资源。Wazuh dashboard 通过单独的 SocTalk 托管路径暴露;1514 上的 agent 协议不是 HTTP,因此 K8s Ingress 不适用。
  5. 确保所有 Pod 都设置了 securityContext: { runAsNonRoot: true, allowPrivilegeEscalation: false };如上游设置为其他值则打补丁。
  6. 将镜像锁定到 digest,而非 latest

TheHive

对象预期分类备注
Deployment(TheHive 应用)NS-OK
StatefulSet(Cassandra 或外部 DB 支持的变体)NS-OK使用内嵌 Cassandra;外部 Cassandra 是后续版本选项
Service(TheHive Web + API 在 9000)NS-OK
ConfigMap(application.conf)NS-OK由 SocTalk 渲染的每租户配置
Secret(管理员凭据、本租户 Cortex 的 Cortex API key)NS-OK
PersistentVolumeClaim(Cassandra 数据、索引数据)NS-OK
ServiceAccountNS-OK
IngressPATCH 或禁用与 Wazuh 相同:dashboard 通过 MSSP 侧带租户路由的代理暴露,而非按命名空间的 Ingress
Job(bootstrap / init)NS-OK用于首次运行的证书生成 / DB 初始化,可接受
CustomResourceDefinitionFORBIDDEN:如存在则必须放在 soctalk-system chart 中
ClusterRole / ClusterRoleBinding在租户 chart 中 FORBIDDEN

预期补丁

  1. 移除 Ingress;仅使用 ClusterIP Service。
  2. 将 Cassandra 锁定到 digest;设置与容量规划相匹配的资源限制。
  3. 确保 init Job 是幂等的(重复运行无害)。
  4. 无 CRD 依赖。

Cortex

对象预期分类备注
Deployment(Cortex 应用)NS-OK
StatefulSet(Elasticsearch 或兼容索引)NS-OK内嵌 ES;外部 ES 为后续版本
Service(Cortex API 在 9001)NS-OK
ConfigMap(application.conf、analyzer 列表)NS-OK
Secret(管理员、服务间令牌)NS-OK
PersistentVolumeClaimNS-OK
ServiceAccountNS-OK
Job(analyzer 注册)若幂等则 NS-OK
IngressPATCH 或禁用
PrivilegedContainer(用于 analyzer 沙箱的 Docker-in-Docker,如上游采用此模式)FORBIDDEN:打补丁需要 Docker 沙箱的 Cortex analyzer 不在本版本范围内。仅使用进程内运行或调用沙箱化外部服务的 analyzer

已知风险:Cortex 历来将某些 analyzer 作为子进程或 Docker 容器运行。本版本仅限于不需要特权主机访问的“纯代码”analyzer。analyzer 列表在 values 中锁定;需要 Docker-in-Docker 的 analyzer 在预置时被拒绝。

集群前置条件清单(并入安装指南 + soctalk-system chart 前置检查)

审计之后,以下内容不在租户 chart 范围内,且必须在 soctalk-tenant 应用到任何命名空间之前就存在于集群中:

前置条件原因来源
K3s 1.30+(或兼容的 K8s 1.30+)基线加上 ValidatingAdmissionPolicy v1MSSP 职责
强制执行 NP 的 CNI(Cilium 为主,Calico 为备)隔离强制执行MSSP 职责
cert-managerIngress 的 TLS、每租户 Wazuh 证书签发MSSP 职责;安装指南提供 helm install 配方
Ingress 控制器(K3s 中默认 Traefik,ingress-nginx 常见)MSSP UI + 客户 UI + 每租户 WebUI 路由MSSP 职责
动态 StorageClass(local-path、longhorn、云厂商 CSI 等)PVC 供给MSSP 职责
若使用 CSI 快照则需 VolumeSnapshotClass备份/恢复 runbook(仅文档)可选

soctalk-system chart 包含一个预安装钩子(helm.sh/hook: pre-install),用于验证:

  • 强制执行 NP 的 CNI 处于活动状态(探测 Cilium 或 Calico 标记)
  • cert-manager CRD 已存在
  • 已设置默认 StorageClass

若有任何一项缺失,钩子会快速失败并给出可操作的错误消息。

打补丁策略

两条路径:

  1. values 驱动的覆盖:优先使用上游 chart 中可禁用不需要对象的 values(例如 ingress.enabled: false、当上游的策略比我们的更宽松时使用 networkPolicy.enabled: false、将 rbac.create: true 限定为仅命名空间级)。
  2. Kustomize 风格的 overlay(Helm 的 kustomize 集成或 post-render 钩子),用于无法通过 values 禁用的对象:移除 ClusterRole、去掉 hostPath 卷、设置 securityContext

我们将上游 chart 以锁定版本的子 chart 依赖形式纳入 charts/soctalk-tenant/charts/,而非作为 helm repo 引用。这使我们能够:

  • 锁定到精确版本(不会有上游意外更新)
  • 按需应用补丁,而不依赖上游 PR 被接受
  • 将我们的捆绑包签名为单一制品(cosign 落地后的后续版本)

如果打补丁后上游仍无法满足我们的需求,回退方案是编写 SocTalk 原生模板,用我们自己的 manifest 调用相同的容器镜像。发布前验证针对每个 chart 决定是否采用此方案。

已知的未知项(由发布前验证解决)

需要实际 helm template 运行 + 检查才能确认的项:

  • [ ] Wazuh:所选 chart 版本是否需要 CRD 以实现 operator 驱动的部署?如果需要,将 CRD 移至 soctalk-system chart。
  • [ ] TheHive:Cassandra 是否需要具备特定特性的 StorageClass(例如仅 RWO、最低 IOPS)?记录在容量规划中。
  • [ ] Cortex:默认启用了哪些 analyzer,是否有任何一个需要 Docker-in-Docker?产出一份安全 analyzer 的允许列表。
  • [ ] 所有 chart:是否有任何 JobCronJob 使用超出命名空间范围的 ServiceAccount 运行?打补丁改为命名空间本地 SA。
  • [ ] 所有 chart:是否有任何 initContainer 带有 privileged: truehostPath 挂载?打补丁或替换。
  • [ ] 所有 chart:默认的 resources.requestslimits:与容量规划配置进行对比;在需要时通过 values 覆盖。

每个未决项都会成为一条发布前验证清单条目。本次 spike 的产出是一张填好的分类表以及可放入 charts/soctalk-tenant/charts/ 的已打补丁 chart。

输出制品(发货前产出)

本次 spike 产出:

  1. 已分类的对象清单(用实际渲染出的对象填充第 3 节的表格)。
  2. 已打补丁的 chart 捆绑包,以锁定版本签入 charts/soctalk-tenant/charts/wazuh/thehive/cortex/
  3. 集群前置条件清单,并入安装指南。
  4. Cortex 的 analyzer 允许列表(仅含安全项的集合)。
  5. 每个子 chart 的 values schema 片段(SocTalk 将按租户提供的输入项)。

本次 spike 的完成是 Helm chart 实现的前置条件。

基于 Apache 2.0 许可证发布。