bigywater.tech
Kubernetes · 91

用户模拟:--as 与 RBAC

--as 是怎么实现的?谁有资格模拟别人?能不能顺便把自己的权限也带上?借一个高权限的组会怎样?这篇用管理员和一个只有 view 的 ServiceAccount 把模拟的权限边界逐项验证一遍。

--as
请求里带 Impersonate-User 头,服务端按被模拟者鉴权
resourceNames: [alice]
把 impersonate 权限限制到只能模拟 alice,模拟 bob 或带 system:masters 组都被拒
不叠加
模拟之后只用被模拟者的权限,模拟者自己的权限不起作用

管理员模拟

实测 · 本机执行输出
  kubectl get pods --as=alice(alice 没有任何权限):退出码 1;['Error from server (Forbidden): pods is forbidden: User "alice" cannot list resource "pods" in API group "" in the namespace "k85"']
  给 alice 绑定 view 之后:退出码 0;['No resources found in k85 namespace.']
  alice 访问别的命名空间 default:退出码 1;['Error from server (Forbidden): pods is forbidden: User "alice" cannot list resource "pods" in API group "" in the namespace "default"']
  kubectl auth whoami --as=alice --as-group=dev --as-group=ops:username=alice;groups=['dev', 'ops', 'system:authenticated'](服务端自动补了 system:authenticated)
  加 --as-uid=uid-123 --as-user-extra=scopes=read:uid=uid-123;extra={'scopes': ['read']}
  只写 --as-group 不写 --as:退出码 1;['Error in configuration: requesting uid, groups or user-extra for kind-kx-main without impersonating a user']

管理员 kubectl get pods --as=alice:alice 没有任何权限,返回 Forbidden: User "alice" cannot list resource "pods" …;给 alice 绑定 view 之后成功,但访问 default 命名空间仍被拒。kubectl auth whoami --as=alice --as-group=dev --as-group=ops 得到 username=alice、groups=[dev, ops, system:authenticated](服务端补上 system:authenticated);加 --as-uid、--as-user-extra 得到对应的 uid 和 extra。只写 --as-group 不写 --as 会被 kubectl 直接拒绝(without impersonating a user)。

谁有资格模拟

实测 · 本机执行输出
  ServiceAccount caller(只有 view)直接 get pods:退出码 0;['No resources found in k85 namespace.']
  caller 加 --as=alice:退出码 1;['Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:k85:caller" cannot impersonate-on:user-info:list resource "pods" in API group "" in the namespace "k85"']
  授予 impersonate users(resourceNames: [alice])之后 --as=alice:退出码 0;['No resources found in k85 namespace.']
  换成 --as=bob:退出码 1;['Error from server (Forbidden): users "bob" is forbidden: User "system:serviceaccount:k85:caller" cannot impersonate resource "users" in API group "" at the cluster scope']
  --as=alice --as-group=system:masters(想借 masters 组提权):退出码 1;['Error from server (Forbidden): groups "system:masters" is forbidden: User "system:serviceaccount:k85:caller" cannot impersonate resource "groups" in API group "" at the cluster scope']
  模拟成功时 whoami 看到的是:alice(caller 自己的身份被替换,不是叠加)

ServiceAccount caller(只有 view)自己读 pods 没问题;加 --as=alice 被拒,消息里的动词是 impersonate-on:user-info:list(这是新版本里更细的模拟授权的写法,我没有深入验证它的语义)。给它一条 impersonate users(resourceNames: [alice])的权限后,--as=alice 成功;换成 --as=bob 被拒(users "bob" is forbidden … cannot impersonate resource "users");--as=alice --as-group=system:masters 也被拒(groups "system:masters" is forbidden)——组要单独授权,不能顺手带上。模拟成功时 whoami 看到的用户名是 alice,caller 自己的身份被替换而不是叠加。

只取被模拟者的权限

实测 · 本机执行输出
  caller 模拟 alice 读 secrets(alice 只有 view,view 不含 secrets):退出码 1;['Error from server (Forbidden): secrets is forbidden: User "alice" cannot list resource "secrets" in API group "" in the namespace "k85"']
  给 caller 自己 edit 之后,caller 自己读 secrets:退出码 0;['No resources found in k85 namespace.']
  但 caller 模拟 alice 读 secrets 仍然:退出码 1;['Error from server (Forbidden): secrets is forbidden: User "alice" cannot list resource "secrets" in API group "" in the namespace "k85"'](模拟之后用的是 alice 的权限)
  管理员看 alice 能做什么(auth can-i --list --as=alice):81 行;前几条:['selfsubjectreviews.authentication.k8s.io [] [] [create]', 'selfsubjectaccessreviews.authorization.k8s.io [] [] [create]', 'selfsubjectrulesreviews.authorization.k8s.io [] [] [create]']

给 caller 自己 edit 之后,它自己读 secrets 成功;但 caller 模拟 alice 读 secrets 仍是 Forbidden: User "alice" cannot list resource "secrets" …——模拟之后用的是 alice 的权限,caller 自己的权限不会叠加。管理员用 kubectl auth can-i --list --as=alice 能列出 alice 在该命名空间能做的 81 行。排查“某个用户为什么没权限”时,以他的身份试一遍最直接;而 impersonate 权限本身就等于“可以成为任何被授权的人”,要谨慎授予。

分步演示

用户模拟
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / kind(Docker 里的单节点或多节点真实集群,节点是 Docker Desktop 虚拟机里的容器)/ kubectl;用空的 kubeconfig 之外的独立 kubeconfig,不碰用户自己的集群;计时用 date +%s%N / kubectl 事件时间戳,数字每次运行会有小幅抖动。三节点 kind 集群 kx-main(Kubernetes v1.37.0);“管理员”是 kind 生成的 kubeconfig 身份(system:masters);ServiceAccount 的令牌由 kubectl create token 生成,用 --server --token 访问;alice、bob 是不存在的用户名,只通过 RBAC 绑定定义权限;每种情形各一次
    • 没有验证:impersonate-on:* 这类细化动词的完整语义与启用条件;审计日志里 impersonatedUser 字段(需要审计策略,见 k18);通过 HTTP 头 Impersonate-Extra-* 传递更多属性;模拟 ServiceAccount(serviceaccounts 资源)的授权方式;kubeconfig 里写死 as 的做法
    京ICP备2026067502号-1京公网安备11010502063487号