授权

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

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

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

授权裁决

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

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

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

授权中使用的请求属性

Kubernetes 只审查以下 API 请求属性

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

请求动词和授权

非资源请求

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

资源请求

要确定资源 API 端点的请求动词,Kubernetes 会映射所使用的 HTTP 动词,并考虑请求是否作用于单个资源或资源集合。

HTTP 动词请求动词
POSTcreate
GETHEADget(对于单个资源)、list(对于集合,包括完整对象内容)、watch(用于监视单个资源或资源集合)
PUTupdate
PATCHpatch
DELETEdelete(对于单个资源)、deletecollection(对于集合)

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

  • 身份验证 的特殊情况
    • 核心 API 组中 usersgroupsserviceaccounts 上的 impersonate 动词,以及 authentication.k8s.io API 组中的 userextras
  • 证书签名请求的授权
    • 证书签名请求的 approve 动词,以及对现有批准的修订的 update
  • RBAC
    • rbac.authorization.k8s.io API 组中 rolesclusterroles 资源上的 bindescalate 动词。

授权上下文

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 动态配置权限策略。
节点
一种特殊用途的授权模式,它根据计划运行的 Pod 来授予 Kubelet 权限。要详细了解节点授权模式,请参阅 节点授权
Webhook
Kubernetes webhook 模式 用于授权,进行同步 HTTP 调用,阻塞请求,直到远程 HTTP 服务响应查询。您可以编写自己的软件来处理调用,或使用生态系统中的解决方案。

授权模式配置

您可以使用 命令行参数 或作为一项 Beta 功能使用 配置文件 来配置 Kubernetes API 服务器的授权程序链。

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

命令行授权模式配置

功能状态: Kubernetes v1.8 [稳定]

您可以使用以下模式

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

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

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

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

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

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

功能状态: Kubernetes v1.30 [beta]

作为一项 beta 功能,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/v1beta1
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:
        # - KubeConfig: 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: KubeConfig
        # Path to KubeConfigFile for connection info
        # Required, if connectionInfo.Type is KubeConfig
        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.ac.cn/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.user.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.30 升级到 Kubernetes 1.31,则需要确保配置文件采用 Kubernetes 1.31 可以理解的格式,然后再升级集群。如果您降级到 1.30,则需要适当地设置配置。

授权配置和重新加载

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

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

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

升级路径

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

  • 在该命名空间中挂载任意 Secrets
    • 可用于访问专用于其他工作负载的机密信息。
    • 可用于获取权限更高的 ServiceAccount 的服务帐户令牌。
  • 在该命名空间中使用任意 ServiceAccounts
    • 可以以另一个工作负载(模拟)的身份执行 Kubernetes API 操作。
    • 可以执行 ServiceAccount 拥有的任何特权操作。
  • 在该命名空间中挂载或使用专用于其他工作负载的 ConfigMaps
    • 可用于获取专用于其他工作负载的信息,例如数据库主机名。
  • 在该命名空间中挂载专用于其他工作负载的卷
    • 可用于获取专用于其他工作负载的信息,并对其进行更改。

检查 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 年 5 月 12 日 下午 2:28 PST:修复 authorization.md 中的标题 (8201801a97)