Files
hacktricks-cloud/src/pentesting-cloud/kubernetes-security/kubernetes-role-based-access-control-rbac.md
T

11 KiB
Raw Blame History

Kubernetes Role-Based Access Control(RBAC)

{{#include ../../banners/hacktricks-training.md}}

Role-Based Access Control (RBAC)

Kubernetes has an authorization module named Role-Based Access Control (RBAC) that helps to set utilization permissions to the API server.

RBACs permission model is built from three individual parts:

  1. Role\ClusterRole ­ 实际的权限。它包含表示一组权限的 rules。每条 rule 都包含 resourcesverbs。verb 是将应用到 resource 上的 action。
  2. Subject (User, Group or ServiceAccount) 将接收 permissions 的 object。
  3. RoleBinding\ClusterRoleBinding Role\ClusterRole 和 subject 之间的 connection。

Kubernetes RBAC diagram showing RoleBinding connecting a ServiceAccount subject to Role permissions

Roles” 和 “ClusterRoles” 的区别只在于 role 会应用在哪里 —— “Role” 只会授予对 onespecific namespace 的 access,而 “ClusterRole” 可以在 cluster 的 all namespaces 中使用。此外,ClusterRoles 也可以授予对以下内容的 access:

  • cluster-scoped resources(例如 nodes)。
  • non-resource endpoints(例如 /healthz)。
  • namespaced resources(例如 Pods),across all namespaces

Kubernetes 1.6 开始,RBAC policies 默认是 enabled 的。但要启用 RBAC,你可以使用类似这样的方式:

kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options

现代集群也可以使用 --authorization-config 配置 API server authorizer 链,该参数指向一个 AuthorizationConfiguration 文件。这个文件可以定义有序的 authorizers、多个 webhook authorizers、webhook 超时、failurePolicy、缓存设置,以及决定哪些请求会发送到 webhook 的 CEL matchConditions。在安全审查中,如果存在 --authorization-config,不要只看 --authorization-mode:读取引用的文件,并检查 webhook 是否可以在 NoOpinion 时 fail openmatchConditions 是否会跳过敏感资源,以及所有 API server 副本是否使用等价的 authorization 配置。

在审查匿名 API 暴露时,也要检查 authentication 配置。--authentication-config 可以将 anonymous authenticator 限定到特定路径,例如 /livez/readyz/healthz。匿名 health endpoint 访问并不等同于对 Kubernetes 资源的匿名访问;危险情况是存在某条 RBAC 或 authorizer 路径,让 system:anonymoussystem:unauthenticated 读取或修改真实的 API 对象。

最后,把 system:masters 中的成员资格视为 cluster-admin 等价。属于这个组的用户或证书拥有不受限制的 API 访问权限,会绕过正常的 RBAC 和 webhook authorization 限制,因此,添加这个组的身份映射可能比普通的 RoleBinding 输出更重要。

Templates

RoleClusterRole 的 template 中,你需要指定 role 的名称namespace(在 roles 中),然后是 role 的 apiGroupsresourcesverbs

  • apiGroups 是一个数组,包含此规则适用的不同 API namespaces。例如,Pod 定义使用 apiVersion: v1。它可以具有诸如 rbac.authorization.k8s.io 或 [*] 这样的值。_
  • resources 是一个数组,定义此规则适用于哪些资源。你可以使用以下命令查看所有资源:kubectl api-resources --namespaced=true
  • verbs 是一个数组,包含允许的动词。Kubernetes 中的 verb 定义了你需要对资源执行的操作类型。例如,list verb 用于资源集合,而 "get" 用于单个资源。

Rules Verbs

(This info was taken from the docs)

HTTP verb request verb
POST create
GET, HEAD get (for individual resources), list (for collections, including full object content), watch (for watching an individual resource or collection of resources)
PUT update
PATCH patch
DELETE delete (for individual resources), deletecollection (for collections)

Kubernetes 有时会使用专门的 verbs 通过额外权限进行 authorization。例如:

  • PodSecurityPolicy
  • policy API group 中 podsecuritypolicies resources 上的 use verb。
  • RBAC
  • rbac.authorization.k8s.io API group 中 rolesclusterroles resources 上的 bindescalate verbs。
  • Authentication
  • core API group 中 usersgroupsserviceaccounts 上的 impersonate verb,以及 authentication.k8s.io API group 中的 userextras

Kubernetes v1.36 也将 constrained impersonation 作为 beta feature 引入。集群不再只授予传统的全有或全无 impersonate verb,而是可以授予特定模式的 verbs,例如 impersonate:user-infoimpersonate:serviceaccountimpersonate:arbitrary-nodeimpersonate:associated-node,以及目标资源上的特定操作 verbs,例如 impersonate-on:user-info:list。审查时要同时看两部分:subject 可以 impersonate 的身份,以及 impersonating 时它能够执行的操作。传统的 impersonate rules 仍然可能允许更广泛的访问,因此,除非 API server 版本和 access-review 证据确认,否则不要假设看起来受限的 verbs 一定会被强制执行。

Warning

你可以通过执行 kubectl api-resources --sort-by name -o wide 找到每个 resource 支持的所有 verbs

Examples

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: defaultGreen
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]

例如,你可以使用一个 ClusterRole 来允许某个特定用户运行:

kubectl get pods --all-namespaces

RoleBinding 和 ClusterRoleBinding

来自 docs role binding 会将 role 中定义的权限授予一个 user 或一组 users。它保存一个 subjects 列表(users、groups 或 service accounts),以及被授予的 role 的引用。RoleBinding 在特定的 namespace 内授予权限,而 ClusterRoleBinding 则在 cluster-wide 范围内授予该访问权限。

apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
name: jane # "name" is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io

Permissions 是 additive,所以如果你有一个具有“list”和“delete” secrets 的 clusterRole,你可以通过一个具有“get”的 Role 来添加它。因此要注意,并始终测试你的 roles 和 permissions,并且 明确 specify 什么是 ALLOWED,因为默认情况下 everything is DENIED。

值得检查的细节

RBAC 使用资源名称时,采用的是它们在 API URLs 中出现的形式,而不是 YAML 的 kind。Pod 是 podsDeployment 是 deployments,而 subresources 会用斜杠表示,例如 pods/logpods/execpods/portforwardpods/ephemeralcontainersdeployments/scaleserviceaccounts/tokennodes/proxyservices/proxy。对 pods 的 permission 不会自动授予对 pods/execpods/log 的访问权限。

resourceNames 可以将某些 requests 限制为特定的 object names

rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["app-config"]
verbs: ["get", "update"]

这不会按名称限制顶层的 createdeletecollection。对于 listwatch,客户端必须包含匹配的 metadata.name 字段选择器,否则该请求不会被该规则授权:

kubectl get configmaps -n default --field-selector=metadata.name=app-config

使用 exact access reviews 进行高影响检查:

kubectl auth can-i create pods/exec -n default
kubectl auth can-i create serviceaccounts/token -n default
kubectl auth can-i impersonate users
kubectl auth can-i bind clusterroles.rbac.authorization.k8s.io
kubectl auth can-i escalate clusterroles.rbac.authorization.k8s.io
kubectl auth can-i impersonate-on:user-info:list pods -n default

枚举 RBAC

# Get current privileges
kubectl auth can-i --list
# use `--as=system:serviceaccount:<namespace>:<sa_name>` to impersonate a service account

# List Cluster Roles
kubectl get clusterroles
kubectl describe clusterroles

# List Cluster Roles Bindings
kubectl get clusterrolebindings
kubectl describe clusterrolebindings

# List Roles
kubectl get roles
kubectl describe roles

# List Roles Bindings
kubectl get rolebindings
kubectl describe rolebindings

滥用 Role/ClusterRoles 进行权限提升

{{#ref}} abusing-roles-clusterroles-in-kubernetes/ {{#endref}}

{{#include ../../banners/hacktricks-training.md}}