跳转到主要内容
Chinese, Simplified

2. 保护对 Kubernetes 控制平面(API 服务器)的访问


Kubernetes 中的 API 访问控制是一个三步过程。 首先,对请求进行身份验证,然后检查请求的有效授权,然后执行请求准入控制,最后授予访问权限。 但在身份验证过程开始之前,确保正确配置网络访问控制和 TLS 连接应该是第一要务。

2.4 Kubernetes API访问授权最佳实践


请求通过身份验证后,Kubernetes 会检查是否应允许或拒绝经过身份验证的请求。该决定基于可用的授权模式(启动 kube-apiserver 时启用),并取决于包括用户、组、额外(自定义键值标签)、API 资源、API 端点、API 请求动词(获取、列表、更新)等属性、patch 等)、HTTP 请求动词(get、put、post、delete)、资源、子资源、命名空间和 API 组。

使用 RBAC


Kubernetes 中的 RBAC 取代了以前可用的 ABAC 方法,是授权 API 访问的首选方法。要启用 RBAC,请以 $ kube-apiserver --authorization-mode=RBAC 的形式启动 API 服务器。同样重要的是要记住 Kubernetes 中的 RBAC 权限本质上是附加的,即没有“拒绝”规则。

Kubernetes 有两种类型的角色——Role 和 ClusterRole,这些角色可以通过称为 RoleBinding 和 ClusterBinding 的方法授予。但是,由于 ClusterRole 的范围很广(Kubernetes 集群范围),因此鼓励使用 Roles 和 RoleBindings 而不是 ClusterRoles 和 ClusterRoleBindings。

以下是您需要注意的内置默认角色:

集群管理员:集群管理员是一个类似“root”或“超级用户”的角色,允许对集群中的任何资源执行任何操作。因此,在向任何用户授予此角色时应谨慎行事。快速检查以了解谁被授予了特殊的“集群管理员”角色;在这个例子中,它只是“masters”组:

$ kubectl describe clusterrolebinding cluster-admin
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
Role:
Kind:  ClusterRole
Name:  cluster-admin
Subjects:
Kind   Name            Namespace
----   ----            ---------
Group  system:masters

管理员:此角色允许对限制在命名空间内的资源进行无限制的读/写访问。它类似于 clutter-admin,允许在命名空间内创建角色和角色绑定。分配此角色时要格外小心。

编辑:此角色允许限制在命名空间内的读/写访问,但查看或修改角色或角色绑定的能力除外。但是,此角色允许访问 ServiceAccount 的秘密,这些秘密可用于获得(提升权限)对通常不可用的受限 API 操作的访问权限。

View:最受限制的内置角色,允许对命名空间中的对象进行只读访问。访问不包括查看机密、角色或角色绑定。

ServiceAccount 角色范围为特定于应用程序的角色


始终向 ServiceAccount 授予特定于应用程序的上下文所需的角色。为了促进最低权限的安全实践,Kubernetes 将分配给 ServiceAccounts 的 RBAC 权限限定在默认情况下仅在 kube-system 命名空间内工作。为了增加权限的范围,例如,下面显示了将“devteam”命名空间中的只读权限授予“devteamsa”服务帐户——您需要创建角色绑定来增加权限的范围。

$ kubectl create rolebinding dev-sa-view --clusterrole=view --serviceaccount=devteam:devteamsa --namespace=devteam

不要授予“升级”和“绑定”角色


确保不要在 Role 或 ClusterRole 上授予升级或绑定动词。 Kubernetes 实现了一种通过编辑角色和角色绑定来防止权限提升的好方法。 该功能可防止用户创建或更新他们自己无权访问的角色。 因此,如果您授予升级或绑定角色,您基本上是在规避权限升级预防功能,恶意用户可以升级他们的权限。

作为参考,遵循 ClusterRole 和 RoleBinding 将允许 non_priv_user 授予其他用户在命名空间 non_priv_user_namespace 中的管理、编辑、查看角色:

 

# Create ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: role-grantor
rules:
  - apiGroups: ['rbac.authorization.k8s.io']
    resources: ['rolebindings']
    verbs: ['create']
  - apiGroups: ['rbac.authorization.k8s.io']
    resources: ['clusterroles']
    verbs: ['bind']
    resourceNames: ['admin', 'edit', 'view']

 

# Create RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-grantor-binding
  namespace: non_priv_user_namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: role-grantor
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: non_priv_user

检查并禁用不安全端口


确保您没有运行 kube-apiserver 并将不安全端口启用为 --insecure-port,因为 Kubernetes 允许通过不安全端口(如果启用)进行 API 调用,而无需执行身份验证或授权。

定期检查授权状态


使用 $ kubectl auth can-i 命令快速查看 API 授权状态。

$ kubectl auth can-i create deployments --namespace dev
yes

该命令根据授权角色返回“yes”或“no”。 虽然您可以使用该命令检查自己的授权状态,但该命令通过与用户模拟命令结合使用来交叉检查其他用户的权限更有用

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

提示:尝试以下命令,如果结果为“是”,则表示允许用户执行任何操作!

    $ kubectl auth can-i '*' '*' --as user_name_to_check

不要使用 --authorization-mode=AlwaysAllow
确保您没有使用 --authorization-mode=AlwaysAllow 标志运行 kube-apiserver,因为它会告诉服务器不需要对传入的 API 请求进行授权。

不鼓励授予 pod 创建角色


授予 pod 创建角色时要小心,因为能够在命名空间中创建 Pod 的用户可以升级他们在命名空间中的角色,并且可以读取所有机密、配置映射或模拟该命名空间中的任何服务帐户。

使用准入控制器


身份验证检查有效凭据,授权检查是否允许用户执行特定任务。但是,您将如何确保经过身份验证和授权的用户正确、安全地执行任务?为了解决这个问题,Kubernetes 支持准入控制功能,它允许修改或验证请求(在成功的身份验证和授权之后)。

Kubernetes 附带了许多准入控制模块。 NodeRestriction 等控制器允许控制 Kubelet 发出的访问请求; PodSecurityPolicy 在与创建和修改 Pod 相关的 API 事件期间触发,可用于对 Pod 强制执行最低安全标准。此外,ValidatingAdmissionWebhooks 和 MutatingAdmissionWebhooks 等控制器允许通过向外部服务(通过 Webhook)发起 HTTP 请求并根据响应执行操作来动态执行策略。这将策略管理和执行逻辑与核心 Kubernetes 分离,并帮助您跨各种 Kubernetes 集群或部署统一安全的容器编排。请参阅此页面,了解如何使用这两个控制器定义和运行自定义准入控制器。

启用/禁用特定准入控制器


内置准入控制器的默认可用性取决于引导 Kubernetes 集群的方式和位置(自定义 Kubernetes 发行版、AWS EKS、GCP Kubernetes Engine 等)。您可以检查当前启用的准入控制器:

$ kubectl -n kube-system describe po kube-apiserver-[name]
Name: kube-apiserver-minikube
...
Containers:
kube-apiserver:
kube-apiserver
 ...
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,
   DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,
   MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota
--enable-bootstrap-token-auth=true

如果要启用或禁用特定准入控制器,可以使用以下命令:

# Enable admission controller
$ kube-apiserver --enable-admission-plugins=[comma separated list of admission controllers]

# Disable admission controller
$ kube-apiserver --disable-admission-plugins=[comma separated list of admission controllers]

确保可用性并配置适当的超时


Kubernetes 通过允许准入 webhook 服务器集成来支持动态准入控制。 虽然动态控制器允许轻松实现自定义准入控制器,但请确保检查 webhook 服务的可用性,因为外部请求可能会引入延迟,从而影响 Kubernetes 集群的整体可用性。

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
---
webhooks:
- name: test-webhook.endpoint.com
timeoutSeconds: 2

原文:https://goteleport.com/blog/kubernetes-api-access-security/

本文:https://jiagoushi.pro/node/1849

Article
知识星球
 
微信公众号
 
视频号