Kubernetes Windows 节点 kubelet subPath 凭据泄露(CVE-2026-76654):受影响面排查、NTLM 出站限制与升级回滚

枫少@KillBoy
枫少@KillBoy
枫少@KillBoy
管理员
427
文章
0
粉丝
云原生安全923字数 2385阅读7分57秒阅读模式
AI智能摘要
Windows节点上subPath挂载可能让kubelet把NetNTLMv2哈希发往外部SMB共享。CVE-2026-76654需平台、非空subPath、可植入链接的卷和可达SMB出口同时成立。文章给出节点与工作负载盘点、修复版本核验,出站限制只是过渡缓解,kubelet不受Pod级NetworkPolicy约束。你的集群核对了吗?
— AI 生成的文章内容摘要

在混合集群里,Windows 节点的 kubelet 需要把卷挂载到容器中,volumeMounts.subPath 是常用配置,用来把 ConfigMap、Secret、hostPath 或 PVC 中的某个子目录单独挂进容器。CVE-2026-76654 的关键在于这条挂载路径:根据公开披露,当 Windows 节点上 Pod 的 subPath 指向一个精心构造的符号链接时,kubelet 在解析过程中可能对该链接目标发起认证,把节点的 NetNTLMv2 哈希发送到外部 SMB 共享。单看这个漏洞的问题,它首先是一个挂载配置和节点出口边界问题,并不直接等同于“集群可被远程利用”。本文只讨论 Windows 节点,按“确认适用条件、盘点受影响对象、升级修复、出站限制、验证与回滚”的顺序展开,linux 节点的行为差异不在此文范围内。

Windows 节点 subPath 解析触发跨界认证的技术示意图

先判断适用条件,再决定处置优先级

把 CVE-2026-76654 当成“所有 Windows 集群都立即高危”并不准确。它需要几个条件同时成立,缺一项,实际暴露面就会显著收窄。建议用下表逐项核对,把“存在风险”与“仅理论上可能”分开记录。

条件判断要点常用核对方式
节点平台节点为 Windows,kubernetes.io/os=windowskubectl get nodes -l kubernetes.io/os=windows
挂载形态Pod 的 volumeMounts 使用了非空 subPath遍历工作负载清单筛选
链接来源卷内可被写入或被植入符号链接、重解析点卷类型、写入权限、内容来源与同步链路
出口可达节点能向外部发起 SMB 或相关认证流量主机防火墙、出口网关、代理与审计日志
版本未修复kubelet 版本低于官方修复版本对照官方安全公告与节点镜像版本

其中“链接来源”最容易被忽略。subPath 本身不会创建符号链接,问题来自卷里已经存在的链接对象,以及 kubelet 在 Windows 上对它的处理方式。因此,如果卷内容来自可写共享、由不可信流程同步、或工作负载本身对卷有写权限,这条判断就需要打上重点标记。

盘点:找出使用 subPath 的 Windows 工作负载与节点

盘点分两步,先确认节点,再确认挂载配置。两者交叉之后,才是一份可执行的整改清单。

节点侧版本与平台核对

kubectl get nodes -l kubernetes.io/os=windows \
  -o custom-columns='NAME:.metadata.name,KUBELET:.status.nodeInfo.kubeletVersion,OSIMAGE:.status.nodeInfo.osImage,CONTAINERRUNTIME:.status.nodeInfo.containerRuntimeVersion'

把结果与节点池、镜像版本、云厂商或发行版的补丁说明对照。注意 kubelet 版本不等于节点镜像版本:部分平台通过替换节点镜像修复,kubelet 语义版本号可能不变,判断依据应以平台公告为准。

工作负载侧 subPath 筛选

kubectl 没有按字段直接过滤 subPath 的语法,用 jq 遍历更稳妥,覆盖 containers 与 initContainers:

kubectl get pods -A -o json | jq -r '
  .items[] as $p
  | (($p.spec.containers // []) + ($p.spec.initContainers // []))[]
  | . as $c
  | ($c.volumeMounts // [])[]
  | select(.subPath != null and .subPath != "")
  | [$p.metadata.namespace, $p.metadata.name, $c.name, .mountPath, .subPath] | @tsv
'

如果集群里有大量工作负载,优先从 Deployment、StatefulSet、DaemonSet 的清单入手,可以避开 Pod 频繁重建带来的噪声:

kubectl get deploy,sts,ds -A -o json | jq -r '
  .items[] as $w
  | ($w.kind + "/" + $w.metadata.namespace + "/" + $w.metadata.name) as $id
  | (($w.spec.template.spec.containers // []) + ($w.spec.template.spec.initContainers // []))[]
  | . as $c
  | ($c.volumeMounts // [])[]
  | select(.subPath != null and .subPath != "")
  | [$id, $c.name, .mountPath, .subPath] | @tsv
'

拿到清单后,再回看每个条目对应的卷类型:hostPath、可写 PVC、从共享目录同步的卷,风险高于只读的 ConfigMap/Secret 投射。调度约束也要看,只有能被调度到 Windows 节点的工作负载才落在本次范围内;如果工作负载同时有 linux 与 Windows 副本,按节点的 nodeSelector 与污点区分。

修复版本核验:以官方公告为唯一依据

CVE-2026-76654 于 2026 年 9 月 24 日前后进入公开披露流程,各发行版与云平台的修复节奏并不一致。仅凭“最新版本”四个字做判断并不可靠,建议按下面的顺序核验:

  1. 查 Kubernetes 官方安全公告,确认受影响的 kubelet 版本区间与修复版本。
  2. 查云厂商或发行版的节点镜像变更记录,确认该镜像是否包含对应修复。例如 GKE 的版本变更日志中记录了 Windows subPath 解析相关漏洞的修复,可作为“平台侧修复如何标注”的参照:GKE 1.34 changelog。
  3. 查自建集群的镜像构建记录与补丁清单,确认 kubelet 二进制来源,而不是只看节点上的版本字符串。

三项交叉后,把节点分成“已修复、待升级、无法确认”三类。无法确认的一律按待升级处理,不要以“看起来是新的”作为结论。

出站限制:作为过渡缓解,而非修复替代

在升级窗口尚未覆盖全部节点时,限制 Windows 节点向外的 NTLM 与 SMB 流量可以显著降低凭据外泄的实际影响,但它只是缓解,不能替代补丁。

需要特别说明一点:kubelet 是节点上的主机进程,它发起的连接不受 Pod 级 NetworkPolicy 约束。因此,指望通过网络策略拦住这条路径通常不成立,控制点应放在主机防火墙或集群出口网络层。

在单台 Windows 节点上,可以用 PowerShell 查看并添加出站规则,先在测试节点验证:

Get-NetFirewallRule -Direction Outbound -Enabled True |
  Where-Object DisplayName -match 'SMB|445' |
  Select-Object DisplayName, Direction, Action

New-NetFirewallRule -DisplayName "Block-Outbound-SMB-445" `
  -Direction Outbound -Protocol TCP -RemotePort 445 -Action Block

执行前必须评估业务依赖。使用 SMB CSI、Azure Files、自建 Samba 共享或依赖 445 的备份、日志采集组件的节点,直接阻断会造成挂载失败或采集中断。可行的做法是按节点池分批启用,并在启用前后对比挂载成功率与业务探针。

验证限制是否真正生效,建议从三个角度取证:

  • 在节点上对目标共享端口做连通性测试,确认连接被拒绝或超时,而不是仍然成功。
  • 查看主机防火墙日志与出口网关的流量记录,确认没有新的 445 出站会话。
  • 查看 Windows 安全日志中的登录类型 3 事件与 SMB 客户端事件,确认没有来自 kubelet 进程上下文的 NTLM 认证尝试。

变更实施:备份、分批升级、验证、回滚

Windows 节点分批升级与回滚双轨流程示意图

变更前准备

  • 导出受影响工作负载清单与节点池配置,至少保留一份集群外的副本,便于回滚时比对差异。
  • 记录当前节点镜像、kubelet 版本、容器运行时版本,作为回滚基线。
  • 确认旧镜像仍可调度。部分平台的节点池升级后旧镜像会被回收,回滚能力需要在变更前验证,而不是事后才发现。
  • 对疑似已暴露的节点账户,提前规划凭据轮换。哈希一旦外泄,仅靠打补丁不能消除风险。

分批升级

先升级一个非生产或低流量的 Windows 节点池,观察一个完整业务周期。每批之间保留观察窗口,重点看三件事:Pod 是否正常重建、卷挂载是否成功、出口限制规则是否随新镜像保留。主机防火墙规则在节点重建后可能不会自动继承,这一点在 Windows 节点池上尤其需要复核。

升级后验证

验证的目标是确认修复行为,而不是复现攻击。可以在隔离测试环境中准备一个指向不可达地址的链接对象,观察 kubelet 是否仍会发起出站认证尝试,同时结合防火墙日志与节点事件日志确认没有新的 NTLM 出站会话。生产环境不建议构造此类测试对象,改为版本核对加日志观察即可。

异常回滚

出现挂载失败、Pod 大面积不可调度或业务探针持续失败时,回滚顺序建议是:先停止扩大升级范围,再把新节点隔离并驱逐工作负载,最后将节点池回退到已验证的旧镜像。回滚后重新核对出口限制规则是否仍然生效,避免在回退过程中出现防护空档。如果期间已经发现可疑认证事件,回滚不能替代凭据轮换与事件调查。

监控与复盘要点

修复完成后,把以下几个观察点纳入日常监控,能帮助发现同类问题的下一次变体:Windows 节点上 kubelet 进程的出站连接、安全日志中的 NTLM 认证事件、SMB 客户端错误集中出现的节点、以及新增使用 subPath 的工作负载。复盘时把“哪些工作负载确实需要 subPath”“哪些卷本不该可写”这两个问题一并回答,往往比单纯升级版本更能降低长期风险。

具体修复版本、受影响区间与厂商处置细节,请以 Kubernetes 官方安全公告和各平台公告为准;本文给出的命令与流程用于授权范围内的自查与变更管理,不构成对任何特定环境的结论。

 
枫少@KillBoy
评论  9  访客  9
    • 风水先生
      风水先生 1

      subPath这个点确实容易被忽略

      • 风与光
        风与光 1

        我们集群Windows节点还不少,得赶紧盘一下

        • 河马先生
          河马先生 1

          出口封445会不会影响SMB CSI挂载啊

          • 风之灵语
            风之灵语 1

            主机防火墙规则节点重建后不继承这点太真实了

            • 肖强
              肖强 1

              NTLM哈希泄露了光升级不够吧

              • 糖糖
                糖糖 0

                用jq筛subPath比一个个翻清单靠谱

                • 风流剑主
                  风流剑主 1

                  想问下只读ConfigMap的subPath风险是不是低一些

                  • 风筝线控制者
                    风筝线控制者 1

                    分批升级加观察窗口比较稳妥

                    • 风尘漫步
                      风尘漫步 2

                      NetworkPolicy拦不住kubelet这个之前真没注意

                    匿名

                    发表评论

                    匿名网友

                    拖动滑块以完成验证