Kubelet 接口等于节点控制权
Kubelet 的 10250 端口提供执行命令、拉取容器日志、查询 Pod 等接口。如果匿名认证开启且没有鉴权,攻击者不需要任何凭据就能在节点上执行命令、进入容器,进而拿下宿主机——历史大规模挖矿事件中,这正是最常见的入口。加固要求写死两条:关闭匿名认证(anonymous.enabled=false),并且鉴权模式使用 Webhook,让请求真正经过 API Server 的授权判断。
基本信息
| 加固项 | 容器节点接口鉴权 |
|---|---|
| 适用平台 | Linux(Kubernetes 节点的 kubelet) |
| 权限要求 | 集群管理员与节点 root |
| 达标判据 | 匿名认证关闭、authorization.mode 为 Webhook、10250 限源 |
| 配置文件 | /var/lib/kubelet/config.yaml 或 kubelet 启动参数 |
典型使用场景
- 自建 K8s 集群节点安全核查
- 攻防演练前收敛最常被利用的节点接口
- 托管集群自查工作节点是否被放开到公网
- 基线巡检确认 kubelet 参数没有被改回默认值
- 应急响应中确认节点是否已被用于执行容器命令
核查现状
核查现状
ss -tlnp | grep ':10250 ' # 监听地址是否为所有网卡
curl -sk --max-time 5 https://127.0.0.1:10250/pods | head -c 200 # 匿名可读即鉴权失效
grep -E 'anonymous-auth|authorization-mode|authentication' /var/lib/kubelet/config.yaml 2>/dev/null
grep -E 'anonymous-auth|authorization-mode' /etc/kubernetes/kubelet.conf 2>/dev/null # 参数也可能在启动参数里
ss -tlnp | grep ':10255 ' # 历史版本的只读端口,若存在必须确认已关闭收敛配置
收敛配置
# /var/lib/kubelet/config.yaml
# authentication:
# anonymous:
# enabled: false
# webhook:
# enabled: true
# authorization:
# mode: Webhook
# 网络层:10250 仅对控制面与监控网段开放(安全组或防火墙限源)
systemctl restart kubelet && systemctl status kubelet --no-pager | head -5 # 重启并确认服务正常核查项与判定
| 核查项 | 达标表现 | 风险表现 |
|---|---|---|
| anonymous.enabled | false | true 时任何来源可调用接口 |
| authorization.mode | Webhook | AlwaysAllow 等于不做鉴权 |
| 10250 来源限制 | 仅控制面与监控网段可达 | 全网可达,尤其对公网开放 |
| 10255 只读端口 | 已关闭 | 部分历史版本默认开启且无鉴权 |
| kubeconfig 中的凭据 | 使用受限的节点身份 | 使用 cluster-admin 类高权限凭据 |
“Kubelet 未授权访问”是攻防演练中的必查项,验证要两层同时做:节点本地确认配置与进程参数生效,网络层确认外部不可达。只在配置文件里改了却忘记重启 kubelet,运行态依旧开放,这类“整改过了仍被打穿”的情况在复盘里出现频率很高。
Kubelet 的接口权限直接对应节点权限:能调 exec 就能进容器,能拉日志就可能读到业务数据。因此除了关闭匿名与限源,还应检查节点上 kubeconfig 的凭据范围,避免节点自身持有远高于其需要的权限。