授权

Kubernetes 授权机制和支持的授权模式的详细信息。

Kubernetes 授权在身份验证之后进行。通常,发出请求的客户端必须先通过身份验证(登录),然后才能允许其请求;但是,Kubernetes 在某些情况下也允许匿名请求。

有关授权如何适应更广泛的 API 访问控制上下文的概述,请阅读控制对 Kubernetes API 的访问

授权决策

Kubernetes API 请求的授权在 API 服务器中进行。API 服务器根据所有策略评估所有请求属性,可能还会咨询外部服务,然后允许或拒绝请求。

API 请求的所有部分都必须由某种授权机制允许才能继续进行。换句话说:默认情况下拒绝访问。

当配置了多个授权模块时,将按顺序检查每个模块。如果有任何授权器*批准*或*拒绝*请求,则立即返回该决定,并且不会咨询其他授权器。如果所有模块对请求都*没有意见*,则请求将被拒绝。总体拒绝决定意味着 API 服务器拒绝请求并响应 HTTP 403(禁止)状态。

授权中使用的请求属性

Kubernetes 仅审查以下 API 请求属性

  • 用户 - 身份验证期间提供的 user 字符串。
  • - 已通过身份验证的用户所属的组名称列表。
  • 额外 - 由身份验证层提供的任意字符串键到字符串值的映射。
  • API - 指示请求是否针对 API 资源。
  • 请求路径 - 到其他非资源端点的路径,例如 /api/healthz
  • API 请求谓词 - API 谓词,例如 getlistcreateupdatepatchwatchdeletedeletecollection,用于资源请求。要确定资源 API 端点的请求谓词,请参阅请求谓词和授权
  • HTTP 请求谓词 - 小写的 HTTP 方法,例如 getpostputdelete,用于非资源请求。
  • 资源 - 正在访问的资源的 ID 或名称(仅限资源请求)-- 对于使用 getupdatepatchdelete 谓词的资源请求,您必须提供资源名称。
  • 子资源 - 正在访问的子资源(仅限资源请求)。
  • 命名空间 - 正在访问的对象的命名空间(仅限命名空间资源请求)。
  • API 组 - 正在访问的API 组(仅限资源请求)。空字符串表示*核心*API 组

请求谓词和授权

非资源请求

/api/v1/.../apis/<group>/<version>/... 以外的端点的请求被视为*非资源请求*,并使用请求的小写 HTTP 方法作为谓词。例如,使用 HTTP 对 /api/healthz 等端点发出 GET 请求将使用 **get** 作为谓词。

资源请求

为了确定资源 API 端点的请求谓词,Kubernetes 映射所使用的 HTTP 谓词,并考虑请求是作用于单个资源还是作用于资源集合

HTTP 谓词请求谓词
POSTcreate
GETHEAD**get**(用于单个资源),**list**(用于集合,包括完整的对象内容),**watch**(用于观察单个资源或资源集合)
PUTupdate
PATCHpatch
DELETE**delete**(用于单个资源),**deletecollection**(用于集合)

Kubernetes 有时会使用专门的谓词检查其他权限的授权。例如

  • 身份验证的特殊情况
    • 核心 API 组中对 `users`、`groups` 和 `serviceaccounts` 的 **impersonate** 谓词,以及 `authentication.k8s.io` API 组中的 `userextras`。
  • CertificateSigningRequests 的授权
    • CertificateSigningRequests 的 **approve** 谓词,以及对现有批准的修订的 **update** 谓词
  • RBAC
    • `rbac.authorization.k8s.io` API 组中对 `roles` 和 `clusterroles` 资源的 **bind** 和 **escalate** 谓词。

授权上下文

Kubernetes 期望 REST API 请求通用的属性。这意味着 Kubernetes 授权可与现有的组织范围或云提供商范围的访问控制系统一起使用,这些系统可以处理 Kubernetes API 以外的其他 API。

授权模式

Kubernetes API 服务器可以使用以下几种授权模式之一来授权请求

AlwaysAllow(始终允许)
此模式允许所有请求,这会带来安全风险。仅当您的 API 请求不需要授权时(例如,用于测试),才使用此授权模式。
AlwaysDeny(始终拒绝)
此模式阻止所有请求。仅用于测试时使用此授权模式。
ABAC基于属性的访问控制
Kubernetes ABAC 模式定义了一种访问控制范例,其中通过使用将属性组合在一起的*策略*向用户授予访问权限。*策略*可以使用任何类型的属性(用户属性、资源属性、对象、环境属性等)。
RBAC基于角色的访问控制
Kubernetes RBAC 是一种根据企业内各个用户的角色来 регулировать 对计算机或网络资源的访问的方法。在此上下文中,访问是指单个用户执行特定任务的能力,例如查看、创建或修改文件。
在此模式下,Kubernetes 使用 rbac.authorization.k8s.io API 组来驱动授权决策,允许您通过 Kubernetes API 动态配置权限策略。
Node
一种特殊用途的授权模式,它根据 kubelet 计划运行的 Pod 授予其权限。要了解有关节点授权模式的更多信息,请参阅节点授权
Webhook
用于授权的 Kubernetes webhook 模式进行同步 HTTP 调用,阻止请求,直到远程 HTTP 服务响应查询。您可以编写自己的软件来处理调用,或使用生态系统中的解决方案。

system:masters 组

system:masters组是一个内置的 Kubernetes 组,它授予对 API 服务器的无限制访问权限。分配给此组的任何用户都具有完整的集群管理员权限,可以绕过 RBAC 或 Webhook 机制施加的任何授权限制。避免将用户添加到此组。如果确实需要授予用户集群管理员权限,则可以创建ClusterRoleBinding到内置的cluster-admin ClusterRole。

授权模式配置

您可以使用配置文件命令行参数来配置 Kubernetes API 服务器的授权器链。

您必须选择两种配置方法之一;同时设置--authorization-config路径和使用--authorization-mode--authorization-webhook-*命令行参数配置授权 webhook 是不允许的。如果您尝试这样做,API 服务器会在启动期间报告错误消息,然后立即退出。

使用授权配置文件配置 API 服务器

特性状态: Kubernetes v1.32 [stable] (默认启用:true)

Kubernetes 允许您配置可以包含多个 webhook 的授权链。该链中的授权项可以具有明确定义的参数,这些参数以特定顺序验证请求,从而为您提供细粒度的控制,例如在失败时明确拒绝。

配置文件方法甚至允许您指定CEL规则,以便在将请求分派到 webhook 之前对其进行预过滤,从而帮助您防止不必要的调用。当配置文件被修改时,API 服务器还会自动重新加载授权器链。

您可以使用--authorization-config命令行参数指定授权配置文件的路径。

如果您想使用命令行参数而不是配置文件,这也是一种有效且受支持的方法。某些授权功能(例如:多个 webhook、webhook 失败策略和预过滤规则)仅在您使用授权配置文件时才可用。

配置示例

---
#
# DO NOT USE THE CONFIG AS IS. THIS IS AN EXAMPLE.
#
apiVersion: apiserver.config.k8s.io/v1
kind: AuthorizationConfiguration
authorizers:
  - type: Webhook
    # Name used to describe the authorizer
    # This is explicitly used in monitoring machinery for metrics
    # Note:
    #   - Validation for this field is similar to how K8s labels are validated today.
    # Required, with no default
    name: webhook
    webhook:
      # The duration to cache 'authorized' responses from the webhook
      # authorizer.
      # Same as setting `--authorization-webhook-cache-authorized-ttl` flag
      # Default: 5m0s
      authorizedTTL: 30s
      # The duration to cache 'unauthorized' responses from the webhook
      # authorizer.
      # Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag
      # Default: 30s
      unauthorizedTTL: 30s
      # Timeout for the webhook request
      # Maximum allowed is 30s.
      # Required, with no default.
      timeout: 3s
      # The API version of the authorization.k8s.io SubjectAccessReview to
      # send to and expect from the webhook.
      # Same as setting `--authorization-webhook-version` flag
      # Required, with no default
      # Valid values: v1beta1, v1
      subjectAccessReviewVersion: v1
      # MatchConditionSubjectAccessReviewVersion specifies the SubjectAccessReview
      # version the CEL expressions are evaluated against
      # Valid values: v1
      # Required, no default value
      matchConditionSubjectAccessReviewVersion: v1
      # Controls the authorization decision when a webhook request fails to
      # complete or returns a malformed response or errors evaluating
      # matchConditions.
      # Valid values:
      #   - NoOpinion: continue to subsequent authorizers to see if one of
      #     them allows the request
      #   - Deny: reject the request without consulting subsequent authorizers
      # Required, with no default.
      failurePolicy: Deny
      connectionInfo:
        # Controls how the webhook should communicate with the server.
        # Valid values:
        # - KubeConfigFile: use the file specified in kubeConfigFile to locate the
        #   server.
        # - InClusterConfig: use the in-cluster configuration to call the
        #   SubjectAccessReview API hosted by kube-apiserver. This mode is not
        #   allowed for kube-apiserver.
        type: KubeConfigFile
        # Path to KubeConfigFile for connection info
        # Required, if connectionInfo.Type is KubeConfigFile
        kubeConfigFile: /kube-system-authz-webhook.yaml
        # matchConditions is a list of conditions that must be met for a request to be sent to this
        # webhook. An empty list of matchConditions matches all requests.
        # There are a maximum of 64 match conditions allowed.
        #
        # The exact matching logic is (in order):
        #   1. If at least one matchCondition evaluates to FALSE, then the webhook is skipped.
        #   2. If ALL matchConditions evaluate to TRUE, then the webhook is called.
        #   3. If at least one matchCondition evaluates to an error (but none are FALSE):
        #      - If failurePolicy=Deny, then the webhook rejects the request
        #      - If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped
      matchConditions:
      # expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
      # CEL expressions have access to the contents of the SubjectAccessReview in v1 version.
      # If version specified by subjectAccessReviewVersion in the request variable is v1beta1,
      # the contents would be converted to the v1 version before evaluating the CEL expression.
      #
      # Documentation on CEL: https://kubernetes.top/docs/reference/using-api/cel/
      #
      # only send resource requests to the webhook
      - expression: has(request.resourceAttributes)
      # only intercept requests to kube-system
      - expression: request.resourceAttributes.namespace == 'kube-system'
      # don't intercept requests from kube-system service accounts
      - expression: "!('system:serviceaccounts:kube-system' in request.groups)"
  - type: Node
    name: node
  - type: RBAC
    name: rbac
  - type: Webhook
    name: in-cluster-authorizer
    webhook:
      authorizedTTL: 5m
      unauthorizedTTL: 30s
      timeout: 3s
      subjectAccessReviewVersion: v1
      failurePolicy: NoOpinion
      connectionInfo:
        type: InClusterConfig

使用配置文件配置授权器链时,请确保所有控制平面节点都具有相同的文件内容。升级/降级集群时,请记下 API 服务器配置。例如,如果从 Kubernetes 1.31 升级到 Kubernetes 1.32,则需要在升级集群之前确保配置文件的格式是 Kubernetes 1.32 可以理解的。如果降级到 1.31,则需要适当地设置配置。

授权配置和重新加载

当 API 服务器观察到文件发生更改时,Kubernetes 会重新加载授权配置文件,如果没有观察到更改事件,则还会按 60 秒的计划重新加载。

命令行授权模式配置

您可以使用以下模式

  • --authorization-mode=ABAC(基于属性的访问控制模式)
  • --authorization-mode=RBAC(基于角色的访问控制模式)
  • --authorization-mode=Node(节点授权器)
  • --authorization-mode=Webhook(Webhook 授权模式)
  • --authorization-mode=AlwaysAllow(始终允许请求;存在安全风险
  • --authorization-mode=AlwaysDeny(始终拒绝请求)

您可以选择多种授权模式;例如:--authorization-mode=Node,RBAC,Webhook

Kubernetes 根据您在 API 服务器命令行上指定的顺序检查授权模块,因此较早的模块具有更高的优先级来允许或拒绝请求。

您不能将--authorization-mode命令行参数与用于使用本地文件配置授权--authorization-config命令行参数组合使用。

有关 API 服务器命令行参数的更多信息,请阅读kube-apiserver参考

通过创建或编辑工作负载进行权限提升

可以直接或通过启用间接工作负载管理的对象在命名空间中创建/编辑 Pod 的用户,可能能够在该命名空间中提升其权限。权限提升的潜在途径包括 Kubernetes API 扩展及其关联的控制器

提权路径

如果您允许攻击者或不受信任的用户在命名空间中运行任意 Pod,则他们可以通过多种方式在该命名空间内获得额外的权限

  • 在该命名空间中挂载任意 Secret
    • 可用于访问 предназначенную для других рабочих нагрузок 的机密信息
    • 可用于获取权限更高的 ServiceAccount 的服务帐户令牌
  • 在该命名空间中使用任意 ServiceAccount
    • 可以作为另一个工作负载执行 Kubernetes API 操作(模拟)
    • 可以执行 ServiceAccount 拥有的任何特权操作
  • 挂载或使用 предназначенные для других рабочих нагрузок 在该命名空间中的 ConfigMap
    • 可用于获取 предназначенную для других рабочих нагрузок 的信息,例如数据库主机名。
  • 挂载 предназначенные для других рабочих нагрузок 在该命名空间中的卷
    • 可用于获取 предназначенную для других рабочих нагрузок 的信息并对其进行更改。

检查 API 访问权限

kubectl 提供了auth can-i子命令,用于快速查询 API 授权层。该命令使用SelfSubjectAccessReview API 来确定当前用户是否可以执行给定操作,并且无论使用哪种授权模式都可以工作。

kubectl auth can-i create deployments --namespace dev

输出类似于以下内容

yes
kubectl auth can-i create deployments --namespace prod

输出类似于以下内容

no

管理员可以将此与用户模拟结合使用,以确定其他用户可以执行的操作。

kubectl auth can-i list secrets --namespace dev --as dave

输出类似于以下内容

no

同样,要检查命名空间dev中名为dev-sa的 ServiceAccount 是否可以列出命名空间target中的 Pod

kubectl auth can-i list pods \
    --namespace target \
    --as system:serviceaccount:dev:dev-sa

输出类似于以下内容

yes

SelfSubjectAccessReview 是authorization.k8s.io API 组的一部分,该组将 API 服务器授权公开给外部服务。此组中的其他资源包括

SubjectAccessReview
对任何用户(而不仅是当前用户)的访问审核。用于将授权决策委托给 API 服务器。例如,kubelet 和扩展 API 服务器使用它来确定用户对其自身 API 的访问权限。
LocalSubjectAccessReview
类似于 SubjectAccessReview,但仅限于特定命名空间。
SelfSubjectRulesReview
返回用户可以在命名空间内执行的操作集的审核。对用户快速总结自己的访问权限或对 UI 隐藏/显示操作很有用。

可以通过创建普通的 Kubernetes 资源来查询这些 API,其中返回对象的响应status字段是查询的结果。例如

kubectl create -f - -o yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
spec:
  resourceAttributes:
    group: apps
    resource: deployments
    verb: create
    namespace: dev
EOF

生成的 SelfSubjectAccessReview 类似于

apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
metadata:
  creationTimestamp: null
spec:
  resourceAttributes:
    group: apps
    resource: deployments
    namespace: dev
    verb: create
status:
  allowed: true
  denied: false

后续步骤

上次修改时间:2024 年 10 月 30 日下午 6:09 PST:添加 systems:master 段落 (cdff2b4b6b)