LabHub
学习 学习路径 课程

KCSA — Kubernetes 安全助理

为什么重新创建账户后权限仍然存在?

在 LabHub 中继续学习

目标

使用真实 bearer 令牌区分 audience、认证和授权,并比较删除后同名重建 SA 时旧令牌与基于名称的绑定如何工作。

为什么重要

撤销权限和吊销凭据不是同一件事。若只看账户名称就判断响应完成,现有权限可能重新作用于新身份。 本实验不使用管理员代理请求,而是通过 TokenRequest、TokenReview 和验证 CA 的真实 HTTPS GET 进行确认。 只使用个人 k3s VM 内的合成 ConfigMap。不要带入生产 kubeconfig 或真实秘密。 环境准备可能需要数分钟。实验时长 55 分钟,如需更多时间,请在到期前延长。VM、文件和令牌会在会话结束时回收。 请提前下载所需观测,但不要下载或共享令牌原文。

已准备的环境与工具

只需直接编写输入 JSON。令牌签发结果由辅助工具以 0600 权限保存在 /opt/fixtures/kcsa-identity-tokens 中,不输出原文。 这些文件只是个人实验内部材料,不应编辑或粘贴进报告。手动签发令牌的请求寿命为 3 小时,请根据服务器响应确认实际过期时间。 内部基线 /opt/fixtures/kcsa-identity-context.json 和 /opt/fixtures/kcsa-identity-lab-context.json 由辅助工具管理,请勿删除或编辑。 act 只执行指定变更。capture 确认观测条件后,将 JSON 保存到 /root/kcsa-identity。 observe 只输出当前观测,grade 不修改资源或学生文件。TokenReview 是令牌验证 API,不会创建持久化对象。

步骤

  1. 用 capture 1 保存 /root/kcsa-identity/baseline.json。调查 kcsa-identity 中 reader SA、identity-client Pod、named-config-reader Role·RoleBinding 和 lesson-policy ConfigMap 的 UID。Pod 和 SA 的自动令牌挂载均为 false,并须保持另一团队 kcsa-identity-other 的正常访问。
  2. 在 /root/kcsa-identity/old-request.json 中编写 authentication.k8s.io/v1 TokenRequest。spec.audiences 为 ["labhub-kcsa-api"],expirationSeconds 为 10800,boundObjectRef 为 apiVersion=v1、kind=Pod、name=identity-client,以及第 1 步观测到的真实 Pod UID。用 act 2 签发,capture 2 将哈希、声明和验证身份记录到 bound-token.json。不要输出令牌原文。
  3. 用 capture 3 保存 /root/kcsa-identity/scoped-request.json。确认原 bearer 令牌查询自己的 lesson-policy 返回 200,查询另一团队返回 403。不能用管理员证书或 --as 请求代替此证据。
  4. 在 /root/kcsa-identity/report-request.json 中编写与第 2 步相同的 TokenRequest,但把 audiences 改为 ["labhub-kcsa-report"]。用 act 4 和 capture 4 保存 audience.json。该令牌的 API GET 应为 401,默认 TokenReview 为 false,明确指定报告 audience 的 TokenReview 为 true。
  5. 在 /root/kcsa-identity/deny-role.json 中编写 rbac.authorization.k8s.io/v1 Role。名称为 named-config-reader,命名空间为 kcsa-identity,rules 是空数组。用 act 5 和 capture 5 保存 rbac-revoked.json。绑定和 SA UID 保持不变,原令牌认证为 true,查询为 403。
  6. 在 /root/kcsa-identity/restore-role.json 中编写同一 Role,但 rules 中放一条 apiGroups=[""]、resources=["configmaps"]、resourceNames=["lesson-policy"]、verbs=["get"] 的规则。用 act 6 恢复 Role,并以 UID 前置条件删除原 SA 后同名重建。用 capture 6 保存 uid-revoked.json。原 Pod 和绑定 UID 保持不变,SA UID 改变;旧令牌在过期前就应认证 false 并返回 401。
  7. 在 /root/kcsa-identity/new-request.json 中编写与第 2 步具有相同 API audience、寿命和原 Pod UID 的 TokenRequest。用 act 7 和 capture 7 保存 new-identity.json。新令牌的 sub 相同但 SA UID 不同,通过现有绑定查询返回 200,旧令牌仍为 401。
  8. 用 act 8 仅删除已调查的原 RoleBinding,并使用 UID·resourceVersion 前置条件。用 capture 8 保存 /root/kcsa-identity/closed.json。同时确认新令牌认证 true、查询 403;旧令牌 401;另一团队身份和 ConfigMap UID 保持不变,正常查询返回 200。

参考

令牌解码不等于签名验证,管理员 --as 请求也不验证该 bearer 令牌的受众或过期时间。 保留已经完成步骤的文件和配置。不要删除历史记录后,用当前状态重新制造相同的成功记录。 进入后续步骤后,过去步骤按记录时的令牌寿命验证,同时另行确认当前步骤的真实状态。 观测新步骤前,请保留紧邻前一步的记录和输入文件。另一团队的 SA、Role、绑定、ConfigMap,以及自己的 Pod、Role、ConfigMap UID 都必须保留到最后。 步骤准备只创建缺失的先前输入与观测,不覆盖当前答案或未完成输入。 若辅助工具等待超时,请检查同一 VM 上的 observe 和状态。不要反复安装或扩大权限来解决。 删除 SA 可能影响其他令牌,不要把本实验当作生产环境无条件适用的响应顺序。 401、403 应结合本次认证请求的上下文理解,并非所有匿名请求都会返回 401。 观测记录是学习材料,不是控制 root 的远程证明或防作弊机制。 官方文档:ServiceAccount 令牌 · 基于名称与命名空间的 RBAC

调查基线身份与安全设置

用 capture 1 保存 /root/kcsa-identity/baseline.json。调查 kcsa-identity 中 reader SA、identity-client Pod、named-config-reader Role·RoleBinding 和 lesson-policy ConfigMap 的 UID。Pod 和 SA 的自动令牌挂载均为 false,并须保持另一团队 kcsa-identity-other 的正常访问。

不要只看名称,也要查看 metadata.uid。分别确认 Pod 和 SA 的自动挂载设置。

签发绑定到真实 Pod UID 的令牌

在 /root/kcsa-identity/old-request.json 中编写 authentication.k8s.io/v1 TokenRequest。spec.audiences 为 ["labhub-kcsa-api"],expirationSeconds 为 10800,boundObjectRef 为 apiVersion=v1、kind=Pod、name=identity-client,以及第 1 步观测到的真实 Pod UID。用 act 2 签发,capture 2 将哈希、声明和验证身份记录到 bound-token.json。不要输出令牌原文。

TokenRequest 的绑定 UID 不能猜测,应从 baseline.json 的 snapshot.pod.metadata.uid 读取。spec 中不需要令牌原文。

真实请求的命名空间边界

用 capture 3 保存 /root/kcsa-identity/scoped-request.json。确认原 bearer 令牌查询自己的 lesson-policy 返回 200,查询另一团队返回 403。不能用管理员证书或 --as 请求代替此证据。

认证 true 不表示本次请求已获允许,请检查实际 GET 的资源和命名空间。

比较受众不同的令牌

在 /root/kcsa-identity/report-request.json 中编写与第 2 步相同的 TokenRequest,但把 audiences 改为 ["labhub-kcsa-report"]。用 act 4 和 capture 4 保存 audience.json。该令牌的 API GET 应为 401,默认 TokenReview 为 false,明确指定报告 audience 的 TokenReview 为 true。

令牌即使尚未过期,受众也可能不同。不部署报告服务器,而是比较明确指定受众的验证。

撤销权限并保留认证

在 /root/kcsa-identity/deny-role.json 中编写 rbac.authorization.k8s.io/v1 Role。名称为 named-config-reader,命名空间为 kcsa-identity,rules 是空数组。用 act 5 和 capture 5 保存 rbac-revoked.json。绑定和 SA UID 保持不变,原令牌认证为 true,查询为 403。

不要删除 Role,只清空 rules。同时观察账户和绑定 UID 相同以及返回 403。

同名的新 ServiceAccount

在 /root/kcsa-identity/restore-role.json 中编写同一 Role,但 rules 中放一条 apiGroups=[""]、resources=["configmaps"]、resourceNames=["lesson-policy"]、verbs=["get"] 的规则。用 act 6 恢复 Role,并以 UID 前置条件删除原 SA 后同名重建。用 capture 6 保存 uid-revoked.json。原 Pod 和绑定 UID 保持不变,SA UID 改变;旧令牌在过期前就应认证 false 并返回 401。

不要以无限权限恢复 Role。请比较同名新账户和原账户的 UID。

连接新身份与现有绑定

在 /root/kcsa-identity/new-request.json 中编写与第 2 步具有相同 API audience、寿命和原 Pod UID 的 TokenRequest。用 act 7 和 capture 7 保存 new-identity.json。新令牌的 sub 相同但 SA UID 不同,通过现有绑定查询返回 200,旧令牌仍为 401。

RoleBinding 中的 SA 主体基于名称和命名空间。请同时确认新令牌成功与旧令牌失效。

精确撤销权限并确认影响

用 act 8 仅删除已调查的原 RoleBinding,并使用 UID·resourceVersion 前置条件。用 capture 8 保存 /root/kcsa-identity/closed.json。同时确认新令牌认证 true、查询 403;旧令牌 401;另一团队身份和 ConfigMap UID 保持不变,正常查询返回 200。

区分认证 false 与认证 true 但授权失败。另一团队的正常请求是撤销范围的对照基线。