Cortex 完成 OSTIF 安全审计:从审计结果走向可执行的部署加固

2026-08-03 51 预计阅读时间: 1 分钟
来源: cncf.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

Open Source Technology Improvement Fund(OSTIF)公布了 Cortex 安全审计的完成情况,审计工作由 Quarkslab 参与实施。Cortex 为 Prometheus 和 OpenTelemetry 提供长期、可扩展的多租户开源存储,因此它不仅承载监控数据,还承担租户隔离、身份传递、对象存储访问和内部服务通信等安全责任。

一次独立审计的价值,不只是列出若干漏洞。它还为维护者和使用者提供了一份风险基线:哪些边界值得重点检查,哪些默认部署方式需要收紧,以及修复措施应该如何进入日常升级流程。

为什么 Cortex 的安全边界比较复杂

Cortex 通常由 Distributor、Ingester、Querier、Query Frontend、Store Gateway、Compactor 等多个组件组成。数据从写入入口流向内部服务、缓存和对象存储,查询请求则沿另一条路径读取并聚合数据。

这种架构带来几个需要持续验证的边界:

  • 多租户隔离:请求携带的租户身份必须可信,查询和写入不能越过租户边界。
  • 外部入口:写入与查询 API 需要认证、限流、超时和请求体大小限制。
  • 内部通信:组件之间的 HTTP 或 gRPC 端口不应直接暴露到不受信任的网络。
  • 对象存储权限:访问 S3、GCS 或兼容存储的凭据应遵循最小权限原则。
  • 资源消耗:高基数标签、超大查询范围和异常并发都可能演变为拒绝服务风险。

来源摘要没有披露具体漏洞、严重等级或修复版本,因此不能据此推断某个 Cortex 版本存在特定缺陷。实际采用时,应结合正式审计报告、Cortex 安全公告和对应版本的发布说明确认影响范围。

审计完成后,使用者应该做什么

安全审计不会自动加固已经运行的集群。运维团队至少需要把审计结论转化为三类工作。

第一类是版本治理。记录当前 Cortex 镜像的精确版本或摘要,对照维护者发布的修复版本升级,并在预发布环境执行写入、查询、压缩和历史数据读取测试。不要长期使用浮动的 latest 标签。

第二类是入口治理。Cortex 常通过租户请求头区分数据归属,但请求头本身不等于认证。生产环境应由可信网关验证调用方身份,再写入或覆盖租户标识;客户端不应能够任意指定其他租户。

第三类是运行时收敛。限制容器权限、网络可达范围和服务账号权限,同时为查询并发、样本摄入和标签基数设置合理上限。这样即使输入异常,影响也更容易限制在单个租户或单个组件内。

可以这样实践:为 Kubernetes 部署增加最小安全基线

下面是一个可改造的 Kubernetes 示例。它不是审计报告给出的官方配置,而是一份通用加固起点。运行前需要替换命名空间、镜像版本、端口和 Pod 标签,使其与实际 Cortex 部署一致。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cortex-distributor
  namespace: observability
spec:
  replicas: 2
  selector:
    matchLabels:
      app: cortex-distributor
  template:
    metadata:
      labels:
        app: cortex-distributor
    spec:
      automountServiceAccountToken: false
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: cortex
          image: quay.io/cortexproject/cortex:v1.18.1
          args:
            - -target=distributor
            - -config.file=/etc/cortex/cortex.yaml
          ports:
            - name: http
              containerPort: 8080
            - name: grpc
              containerPort: 9095
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              cpu: "1"
              memory: 1Gi
          volumeMounts:
            - name: config
              mountPath: /etc/cortex
              readOnly: true
            - name: tmp
              mountPath: /tmp
      volumes:
        - name: config
          configMap:
            name: cortex-config
        - name: tmp
          emptyDir: {}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cortex-distributor-ingress
  namespace: observability
spec:
  podSelector:
    matchLabels:
      app: cortex-distributor
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: monitoring-gateway
      ports:
        - protocol: TCP
          port: 8080

应用前先让 Kubernetes 服务端执行校验:

kubectl apply --dry-run=server -f cortex-hardened.yaml
kubectl apply -f cortex-hardened.yaml
kubectl -n observability rollout status deployment/cortex-distributor

示例中的镜像版本只用于展示固定版本的写法,并不代表它一定是当前推荐版本。上线前应选择包含相关安全修复的受支持版本,最好进一步固定镜像摘要:

image: quay.io/cortexproject/cortex@sha256:REPLACE_WITH_VERIFIED_DIGEST

如果集群启用了默认拒绝网络策略,还需要显式添加 Cortex 组件访问 DNS、成员发现、缓存、对象存储及其他内部组件所需的出站规则。策略过严会导致服务不可用,策略过宽则失去隔离效果,因此应根据真实流量逐项放行。

验证租户身份没有被客户端绕过

可以在测试环境对入口网关做一个简单的负向验证。下面的地址、令牌和租户名称需要替换为实际值:

export CORTEX_URL="https://cortex.example.com"
export ACCESS_TOKEN="replace-with-test-token"

curl --fail-with-body \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "X-Scope-OrgID: another-tenant" \
  "${CORTEX_URL}/api/prom/api/v1/query?query=up"

预期结果取决于网关设计:请求应被拒绝,或者网关应忽略客户端提供的租户头并使用经过认证的租户身份。若普通客户端可以通过修改请求头读取其他租户数据,就必须在入口层修复身份映射逻辑。

这类测试应覆盖查询、远程写入和规则相关入口,并避免在生产环境使用真实跨租户数据做破坏性验证。

把一次审计变成持续控制

采用审计成果时,可以按下面的清单推进:

  • 获取正式审计报告,确认发现项、影响版本、修复状态和剩余风险。
  • 将 Cortex 组件升级到维护者建议的受支持版本,并固定镜像版本或摘要。
  • 确保租户请求头只能由认证网关注入或覆盖。
  • 限制外部入口和组件内部端口的网络可达性。
  • 使用最小权限访问对象存储、Kubernetes API 和密钥系统。
  • 配置摄入、查询、并发与资源限制,并针对单个租户设置保护措施。
  • 在 CI 或预发布环境加入跨租户负向测试和升级回归测试。
  • 订阅 Cortex、OSTIF 及相关依赖的后续安全公告。

独立安全审计提高了 Cortex 风险状况的可见性,但审计完成并不等于部署自动安全。真正决定结果的,是团队能否核对正式发现、及时升级,并把身份校验、网络隔离、最小权限和滥用防护固化到每次发布中。


相关推荐