【Kubernetes】K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制

G皮T 2024-09-16 15:33:01 阅读 50

K8s 的安全认证》系列,共包含以下文章:

K8s 的安全框架和用户认证K8s 的鉴权管理(一):基于角色的访问控制(RBAC 鉴权)K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制服务账号 Service Account

😊 如果您觉得这篇文章有用 ✔️ 的话,请给博主一个一键三连 🚀🚀🚀 吧 (点赞 🧡、关注 💛、收藏 💚)!!!您的支持 💖💖💖 将激励 🔥 博主输出更多优质内容!!!

K8s 的鉴权管理(二):基于属性 / 节点 / Webhook 的访问控制

1.基于属性的访问控制(ABAC 鉴权)2.基于节点的访问控制(node 鉴权)2.1 读取操作2.2 写入操作

3.基于 Webhook 的访问控制3.1 基于 Webhook 的访问控制的架构3.2 基于 Webhook 的访问控制的运行机制

1.基于属性的访问控制(ABAC 鉴权)

✨ 官方文档:https://kubernetes.io/docs/reference/access-authn-authz/abac/

❗ ABAC 鉴权功能从 Kubernetes <code>1.6 版本被弃用。

基于属性的访问控制Attribute-Based Access ControlABAC)通过将属性组合在一起来定义用户可以访问的范围。其策略文件是一个具有多行 JSON 格式的文件,该文件中的每一行都是一个策略(即一个 JSON 对象)。

下表列举了该 JSON 对象应具备的属性。

属性

属性中的字段

版本控制 1️⃣ <code>apiVersion:字符串类型。该字段表示匹配 Kubernetes API 的哪些版本。该字段允许的值为 abac.authorization.kubernetes.io/v1beta1

2️⃣ kind:字符串类型,有效值为 Policy。

spec 1️⃣ <code>user:字符串类型。该字段的值可以是验证通过的用户名,也可以是通过 --token-auth-file 指定的 Token 文件。

2️⃣ group:字符串类型。如果指定了该字段,则它必须是经过身份验证的用户组。使用 system:authenticated 可以匹配所有经过身份验证的用户组;使用 system:unauthenticated 可以匹配所有没有经过身份验证的用户组。

资源匹配 1️⃣ <code>apiGroup:字符串类型,表示匹配一个 Kubernetes API 资源组。使用 * 则匹配所有 API 资源组。也可以具体指定某一个资源组,例如 extensions

2️⃣ namespace:字符串类型,表示匹配某一个命名空间。使用 * 则匹配所命名空间。也可以具体指定某一个命名空间,例如 kube-system

3️⃣ resource:字符串类型,表示匹配的资源类型。使用 * 将匹配所资源。也可以具体指定某一个或者某几个资源,例如 podservice

非资源匹配 <code>nonResourcePath:字符串类型,表示请求的路径。例如:/version/apis。该字段也可以使用通配符。例如,使用 * 则匹配所有非资源请求;使用 /dev/* 则匹配 /dev/ 的所有子路径。
readonly 布尔类型。当该字段被设置为 <code>true 时,资源匹配策略仅适用于 GET、LIST 和 WATCH 操作,而非资源匹配策略仅适用于 GET 操作。

下面是使用 ABAC 鉴权时的几个 JSON 策略。

alice 用户可以对所有资源做任何事情。

{ -- -->

"apiVersion": "abac.authorization.kubernetes.io/v1beta1",

"kind": "Policy",

"spec": {

"user": "alice",

"namespace": "*",

"resource": "*",

"apiGroup": "*"

}

}

Kubelet 用户可以访问任何 Pod 和服务。

{

"apiVersion": "abac.authorization.kubernetes.io/v1beta1",

"kind": "Policy",

"spec": {

"user": "kubelet",

"namespace": "*",

"resource": "pods",

"readonly": true

}

}

Bob 用户可以在命名空间 dev-demo 中访问 Pod。

{

"apiVersion": "abac.authorization.kubernetes.io/v1beta1",

"kind": "Policy",

"spec": {

"user": "bob",

"namespace": "dev-demo",

"resource": "pods",

"readonly": true

}

}

🚀 在实际情况中,通常会把一个 JSON 字符串放到一个 JSON 策略文件中,来作为访问控制的策略文件。在配置完 JSON 策略文件后,在重启 API Server 时需要指定该文件才能获取新的策略。

2.基于节点的访问控制(node 鉴权)

✨ 官方文档:https://kubernetes.io/docs/reference/access-authn-authz/node/

基于节点的访问控制node 鉴权)是专门针对 kubectl 发出的 API 请求的一种鉴权。

🚀 要启用基于节点的访问控制,则需要在启动 API Server 时使用 --authorization-mode=Node 参数。

对于 kubectl 执行的 API 请求,Node 鉴权过程主要包括 读取操作写入操作

2.1 读取操作

kubectl 使用基于节点的方式操作 API 资源时,允许对以下资源进行 读取操作

Pod、Service、Endpoint、NodeSecret、ConfigMap、PVC绑定到 kubelet 节点的与 Pod 相关的持久卷

2.2 写入操作

kubectl 使用基于节点的方式操作 API 资源时,允许对以下的资源进行 写入操作

节点和节点状态(启用 NodeRestriction 准入控制器,以限制 kubelet 只能修改本节点的信息)。Pod 和 Pod 状态(启用 NodeRestriction 准入控制器,以限制 kubelet 只能修改绑定到本节点的 Pod 信息)。Event(事件)。

🚀 由于写入操作需要启用 NodeRestriction(准入控制器),因此在启动 API Server 时,需要在 --enable-admission-plugins 中加入 NodeRestriction,例如:--enable-admission-plugins=...,NodeRestriction,...

3.基于 Webhook 的访问控制

✨ 官方文档:https://kubernetes.io/docs/reference/access-authn-authz/webhook/

基于 Webhook 的访问控制定义了 HTTP 的一个回调接口,从而实现在某些特定事件发生时,该接口的应用会向一个远端的授权服务器发送 HTTP POST 信息。因此,在启用基于 Webhook 的访问控制后,Kubernetes 会调用外部的服务来对用户访问的资源进行授权。

🚀 要启用基于 Webhook 的访问控制,则需要在启动 API Server 时使用 --authorization-mode=webhook 参数。

3.1 基于 Webhook 的访问控制的架构

基于 Webhook 的访问控制的架构如下图所示。

在这里插入图片描述

从架构来看,基于 Webhook 的访问控制其实是一种基于 HTTP 协议的客户端与服务器(<code>Client-Server)架构。由于 Kubernetes 的访问控制是围绕 API Server 进行的,因此,这里的 HTTP 客户端就是 API Server,而 HTTP 服务器端就是远端的授权服务器。在配置 HTTP 客户端 API Server 时,需要使用一个配置文件来指定远端的授权服务器的信息。

下面是 Kubernetes 官方提供的一个 HTTP 客户端配置示例。

# Kubernetes API version

apiVersion: v1

# kind of the API object

kind: Config

# clusters refers to the remote service.

clusters:

- name: name-of-remote-authz-service

cluster:

# CA for verifying the remote service.

certificate-authority: /path/to/ca.pem

# URL of remote service to query. Must use 'https'. May not include parameters.

server: https://authz.example.com/authorize

# users refers to the API Server's webhook configuration.

users:

- name: name-of-api-server

user:

client-certificate: /path/to/cert.pem # cert for the webhook plugin to use

client-key: /path/to/key.pem # key matching the cert

# kubeconfig files require a context. Provide one for the API Server.

current-context: webhook

contexts:

- context:

cluster: name-of-remote-authz-service

user: name-of-api-server

name: webhook

🚀 其中的 clusters 字段代表的是远端的授权服务器。

有了客户端的配置文件后,在启动 API Server 时,除要指定使用 Webhook 的鉴权方式(即设置 --authorization-mode=webhook 参数)外,还需要用 --authorization-webhook-config-file 参数来指定 HTTP 客户端 API Server 的配置文件。

3.2 基于 Webhook 的访问控制的运行机制

在 Kubernetes 配置好基于 Webhook 的访问控制后,在进行鉴权时,API Server 会自动向远端的授权服务器发送一个 HTTP POST 的报文,在该请求中包含一个 JSON 格式的 SubjectAccessReview 对象用来描述当前执行的动作请求。

以下是对 Kubernetes 的资源对象请求进行鉴权的 HTTP POST 报文格式。该报文希望 jane 用户可以获取 Pod 的列表。

{

"apiVersion": "authorization.k8s.io/v1beta1",

"kind": "SubjectAccessReview",

"spec": {

"resourceAttributes": {

"namespace": "kittensandponies",

"verb": "get",

"group": "unicorn.example.org",

"resource": "pods"

},

"user": "jane",

"group": [

"group1",

"group2"

]

}

}

可以看出,SubjectAccessReview 对象中除包含被访问资源和请求的动作信息外,还包含用户的信息。

如果要对 Kubernetes 的非资源对象的请求进行鉴权,则报文格式如下:

{

"apiVersion": "authorization.k8s.io/v1beta1",

"kind": "SubjectAccessReview",

"spec": {

"nonResourceAttributes": {

"path": "/debug",

"verb": "get"

},

"user": "jane",

"group": [

"group1",

"group2"

]

}

}

远端的授权服务器在收到 HTTP POST 报文后,如果鉴权成功,则返回一个 SubjectAccessReview 对象,并在对象中填充 status 字段来允许访问。例如:

{

"apiVersion": "authorization.k8s.io/v1beta1",

"kind": "SubjectAccessReview",

"status": {

"allowed": true

}

}

在远端的授权服务器拒绝请求的 HTTP POST 报文时,也是通过填充 status 字段来拒绝。例如:

{

"apiVersion": "authorization.k8s.io/v1beta1",

"kind": "SubjectAccessReview",

"status": {

"allowed": false,

"reason": "user does not have read access to the namespace"

}

}

如果远端的授权服务器拒绝了 API Server 的请求,同时也想拒绝其他授权者再次对该请求进鉴权,则可以在 status 字段中增加一个 denied 参数。例如:

{

"apiVersion": "authorization.k8s.io/v1beta1",

"kind": "SubjectAccessReview",

"status": {

"allowed": false,

"denied": true,

"reason": "user does not have read access to the namespace"

}

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。