~$ alias kl=kubectl ~$ kl create sa bindsa serviceaccount/bindsa created ~$ kl create role bindsarole --verb=list --resource=pod role.rbac.authorization.k8s.io/bindsarole created ~$ kl create rolebinding bindingsa --serviceaccount=default:bindsa --role=bindsarole rolebinding.rbac.authorization.k8s.io/bindingsa created ~$ kl get secret | grep bindsa bindsa-token-9tq7m kubernetes.io/service-account-token 3 25m ~$ TOKEN=$(kl get secret bindsa-token-9tq7m -o jsonpath='{.data.token}' | base64 -d) ~$ kl config set-credentials bindsa --token=$TOKEN User "bindsa" set. ~$ kl config set-context bindsa --cluster kubernetes --user bindsa Context "bindsa" created.
1 2 3 4 5 6 7 8
测试权限: # 能list pod但不能list deployment
~$ kl --context=bindsa get pod NAME READY STATUS RESTARTS AGE ...... ~$ kl --context=bindsa get deployments Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:default:bindsa" cannot list resource "deployments" in API group "apps" in the namespace "default"
~$ kl --context=bindsa create rolebinding bindingsaview --serviceaccount=default:bindsa --clusterrole=system:aggregate-to-view error: failed to create rolebinding: rolebindings.rbac.authorization.k8s.io is forbidden: User "system:serviceaccount:default:bindsa" cannot create resource "rolebindings" in API group "rbac.authorization.k8s.io" in the namespace "default" 我们发现没法创建rolebinding,那么我们就用高权限的用户给bindsa创建create rolebinding的权限。
~$ kl edit role bindsarole # 添加create rolebinding的权限 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: "2022-02-07T18:22:05Z" name: bindsarole namespace: default resourceVersion: "1175142" uid: c1003090-62ad-4361-bc70-8ca23ce9e637 rules: - apiGroups: - "rbac.authorization.k8s.io" resources: - rolebindings verbs: - create - apiGroups: - "" resources: - pods verbs: - list # 再次执行 ~$ kl --context=bindsa create rolebinding bindingsaview --serviceaccount=default:bindsa --clusterrole=system:aggregate-to-view error: failed to create rolebinding: rolebindings.rbac.authorization.k8s.io "bindingsaview" is forbidden: user "system:serviceaccount:default:bindsa" (groups=["system:serviceaccounts" "system:serviceaccounts:default" "system:authenticated"]) is attempting to grant RBAC permissions not currently held: {APIGroups:[""], Resources:["bindings"], Verbs:["get" "list" "watch"]} ...... 我们发现没法创建rolebinding,因为新的role/clusterrole包含sa原先没有的权限。
~$ alias kl=kubectl ~$ kl create sa escalatesa serviceaccount/escalatesa created ~$ kl create role escalatesarole --verb=list --resource=pod role.rbac.authorization.k8s.io/escalatesarole created ~$ kl create rolebinding escalatesa --serviceaccount=default:escalatesa --role=escalatesarole rolebinding.rbac.authorization.k8s.io/escalatesa created ~$ kl get secret | grep escalatesa escalatesa-token-xz6zh kubernetes.io/service-account-token 3 94s ~$ TOKEN=$(kl get secret escalatesa-token-xz6zh -o jsonpath='{.data.token}' | base64 -d) ~$ kl config set-credentials escalatesa --token=$TOKEN User "escalatesa" set. ~$ kl config set-context escalatesa --cluster kubernetes --user escalatesa Context "escalatesa" created.
1 2 3 4 5 6 7 8
测试权限: # 能list pod但不能list deployment
~$ kl --context=escalatesa get pod NAME READY STATUS RESTARTS AGE ...... ~$ kl --context=escalatesa get deployments Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:default:escalatesa" cannot list resource "deployments" in API group "apps" in the namespace "default"
# 报错,试图提升当前没有的权限,所以即使有了编辑role的权限也没法给role添加新权限。 ~$ kl --context=escalatesa edit role escalatesarole error: roles.rbac.authorization.k8s.io "escalatesarole" could not be patched: roles.rbac.authorization.k8s.io "escalatesarole" is forbidden: user "system:serviceaccount:default:escalatesa" (groups=["system:serviceaccounts" "system:serviceaccounts:default" "system:authenticated"]) is attempting to grant RBAC permissions not currently held: {APIGroups:["apps"], Resources:["deployments"], Verbs:["list"]}
~$ kl --context=escalatesa get pod NAME READY STATUS RESTARTS AGE ...... ~$ kl --context=escalatesa get deployments No resources found in default namespace.
~$ alias kl=kubectl ~$ kl create sa impersonatesa serviceaccount/impersonatesa created ~$ kl create role impersonatesarole --verb=list --resource=pod role.rbac.authorization.k8s.io/impersonatesarole created ~$ kl create rolebinding impersonatesa --serviceaccount=default:impersonatesa --role=impersonatesarole rolebinding.rbac.authorization.k8s.io/impersonatesa created ~$ kl get secret | grep impersonatesa impersonatesa-token-tc95p kubernetes.io/service-account-token 3 34s ~$ TOKEN=$(kl get secret impersonatesa-token-tc95p -o jsonpath='{.data.token}' | base64 -d) ~$ kl config set-credentials impersonatesa --token=$TOKEN User "impersonatesa" set. ~$ kl config set-context impersonatesa --cluster kubernetes --user impersonatesa Context "impersonatesa" created.
1 2 3 4 5 6 7 8
测试权限: # 能list pod但不能list deployment
~$ kl --context=impersonatesa get pod NAME READY STATUS RESTARTS AGE ...... ~$ kl --context=impersonatesa get deployments Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:default:impersonatesa" cannot list resource "deployments" in API group "apps" in the namespace "default"
~$ kl --context=impersonatesa get deployments --as any --as-group system:masters Error from server (Forbidden): users "any" is forbidden: User "system:serviceaccount:default:impersonatesa" cannot impersonate resource "users" in API group "" at the cluster scope
Be aware that users with the permission to create pods can escalate their privileges easily. This is because any service account can be provided in the pod specification. The token secret of the selected service account will be mapped into the container and it can be used for API access. So, the create pod privilege implicitly allows to impersonate any service account within the same namespace.
# user createpod ~$ kl create sa createpod serviceaccount/createpod created ~$ kl create role createpodrole --verb=list,create --resource=pod role.rbac.authorization.k8s.io/createpodrole created ~$ kl create rolebinding createpod --serviceaccount=default:createpod --role=createpodrole rolebinding.rbac.authorization.k8s.io/createpod created ~$ kl get secret | grep createpod createpod-token-dl28b kubernetes.io/service-account-token 3 66s ~$ TOKEN=$(kl get secret createpod-token-dl28b -o jsonpath='{.data.token}' | base64 -d) ~$ kl config set-credentials createpod --token=$TOKEN User "createpod" set. ~$ kl config set-context createpod --cluster kubernetes --user createpod Context "createpod" created.
# user listdeployments ~$ kl create sa listdeployments serviceaccount/listdeployments created ~$ kl create role listdeploymentsrole --verb=list --resource=deployments role.rbac.authorization.k8s.io/listdeploymentsrole created ~$ kl create rolebinding listdeployments --serviceaccount=default:listdeployments --role=listdeploymentsrole rolebinding.rbac.authorization.k8s.io/listdeployments created
测试权限:
1 2 3 4 5 6 7
# 能list pod但不能list deployment
~$ kl --context=createpod get pod NAME READY STATUS RESTARTS AGE ...... ~$ kl --context=createpod get deployments Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:default:createpod" cannot list resource "deployments" in API group "apps" in the namespace "default"
~$ kl --context=createpod get pod NAME READY STATUS RESTARTS AGE ... ~$ kl --context=listdeployments get deployments No resources found in default namespace. ...