原文链接:这些用来审计 Kubernetes RBAC 策略的方法你都见过吗?

认证与授权对任何安全系统来说都至关重要,Kubernetes 也不例外。即使我们不是安全工作人员,也需要了解我们的 Kubernetes 集群是否具有足够的访问控制权限。Kubernetes 社区也越来越关注容器的安全评估(包括渗透测试,配置审计,模拟攻击),如果你是应用安全工程师,或者是安全感知的 DevOps 工程师,最好了解一下 Kubernetes 的授权模型。

Kubernetes 的授权控制原则与大多数系统一样:在授予访问权限时采用最小授权原则。例如,如果某个 Pod 使用了特定的 serviceAccount,那么该 Pod 被限定为只能拥有指定的权限,只能访问特定的资源。

Kubernetes 从 1.6 开始支持基于角色的访问控制机制(Role-Based Access,RBAC),集群管理员可以对用户或服务账号的角色进行更精确的资源访问控制。先简单回顾一下 RBAC 的原理。

1. RBAC 基础概念

RBAC 授权策略会创建一系列的 Role 和 ClusterRole 来绑定相应的资源实体(serviceAccount 或 group),以此来限制其对集群的操作。每一个 Role 都基于 Create, Read, Update, Delete(CRUD)模型来构建,并使用“动词”来应用相应的权限。例如,动词 get 表示能够获取特定资源的详细信息。如果你想获取对 Secrets 的访问权限,可以创建如下的 ClusterRole:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]

关于 RBAC 的更多详细文档请参考 Kubernetes 官方文档CNCF 的博客

2. RBAC 实践

RBAC 授权模型为我们提供了一种精确的访问控制机制,但随着环境越来越复杂,这些 RBAC 配置也越来越难维护。RBAC 配置可能包含了 Roles, RoleBindings, ClusterRoles, ClusterRoleBindings, ServiceAccounts 和 Groups 等,想要跟踪它们之间的关系非常困难。

举个栗子,先创建一个名叫 helm 的 ServiceAccount,然后创建相应的 Role 绑定 “tiller-world” namespace,该 Role 只拥有 list pods 的权限,最后通过创建 RoleBinding 将该 Role 与之前创建的 ServiceAccount 绑定。

apiVersion: v1
kind: ServiceAccount
metadata:
name: helm
namespace: helm-world
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: tiller-user
namespace: tiller-world
rules:
- apiGroups:
- ""
resources:
- pods/portforward
verbs:
- create
- apiGroups:
- ""
resources:
- pods
verbs:
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tiller-user-binding
namespace: tiller-world
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tiller-user
subjects:
- kind: ServiceAccount
name: helm
namespace: helm-world

如果你想知道新创建的授权对象是否仅被授予必要的访问权限,就需要审查这些对象及其在集群中的关系。有时候还需要确保其仅对特定的资源实例具有访问权限,不允许访问所有的资源实例。例如,如果你不想让上面的 ServiceAccount 访问所有的 Secret,只允许它访问特定的 Secret,可以使用 resourceNames 字段指定:

rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["my-pod-secrets"]
verbs: ["get", "watch", "list"]

这个方法的问题在于无法过滤集群中不存在的资源,这意味着如果资源的名称是动态变化的,那么就无法创建相应的 Role,除非在创建 Role 的同时创建资源。

3. 审计很重要

为了查看每个 Role 的作用以及每个资源对象应该能做哪些事情,我们不得不进行一些审计工作。最简单的审计就是确认某个 Service Account 是否拥有 Cluster Admin 的权限,再复杂一点,确认某个 CI/CD Service Account 在指定的 namespace 内是否拥有 Update Pod 的权限。

基于审计的目标,大致可以分为两种审计模式:

  • 资源审计:识别风险最高的资源对象,并查看谁可以访问它们。
  • 账户审计:查看账户的有效权限并确保它们的合理性。

账户审计比较彻底,但很耗时;资源审计可以更快发现问题,但可能会有所遗漏。举例:

  • 资源审计:查看谁能访问某个 Secret 资源,并确保其是否遵循最小授权原则。
  • 账户审计:遍历所有的 user,group,Service Account 和 RoleBinding,确保它们是否被授予正确的访问权限,并只限定在特定的 namespace 内。

下面提供几种命令行工具来帮助大家更方便地审计 RBAC。

4. Kubectl Can-I

某些生产环境不允许安装额外的服务,只能使用 kubectl,我们可以使用 kubectl 的内置命令 kubectl auth can-i 来查看 RBAC 权限。

例如,查看你是否拥有 get pod 的权限:

$ kubectl auth can-i get pods
yes

查看你是否拥有 cluster-admin 的权限:

$ kubectl auth can-i "*" "*"
yes

列出你在某个 namesapce 中拥有的所有权限:

$ kubectl auth can-i --list --namespace=secure

Resources                                       Non-Resource URLs   Resource Names   Verbs
*.* [] [] [*]
[*] [] [*]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]

来点更有趣的,我们还可以通过 Kubernetes 的 Impersonation API 来查看其他账户是否拥有访问特定资源的权限。例如,查看名为 unprivileged-service-account 的 Service Account 是否拥有 get pod 的权限:

$ kubectl auth can-i get pod \
--as system:serviceaccount:secure:unprivileged-service-account
yes

--as 参数用来指定账户名称,类似的参数还有 --as-group,背后的原理实际上是一组传递给 API Server 的请求头。

Kubernetes 中除了有 Service Account 之外还会有 User,每创建一个 Service Account,都会自动创建一个对应的 User,名称格式为:system:serviceaccount:<namespace><serviceaccount>。想知道某个 Service Account 的 username 可以通过它的 yaml 文件来推算:

$ kubectl get serviceaccount unprivileged-service-account -o yaml

apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2019-07-23T17:44:31Z"
name: unprivileged-service-account
namespace: default
resourceVersion: "98089"
selfLink: /api/v1/namespaces/default/serviceaccounts/unprivileged-service-account
secrets:
- name: unprivileged-service-account-token-9cggz

通过将 verbs 字段的值指定为 impersonate,可以让某个用户拥有其他用户的权限,即可以模拟其他用户。例如,管理员可以使用此功能通过暂时模拟其他用户并查看请求是否被拒绝来调试授权策略。

例如,如果你想让非 Cluster Admin 账户能够模拟其他用户,可以创建如下的 ClusterRole:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: impersonator
rules:
- apiGroups: [""]
resources: ["users", "groups", "serviceaccounts"]
verbs: ["impersonate"]

5. Kubectl Who Can

下面介绍的这款工具是 kubectl 的插件,插件名叫 who-can,顾名思义,用来显示哪些账户拥有访问特定资源的权限。安装方法很简单,可以通过 kubectl 的插件管理框架 Krew 来安装:

  1. 安装 krew。参考 https://github.com/kubernetes-sigs/krew/

  2. 安装 who-can

    $ kubectl krew install who-can

假设 secure namespace 中有一个 Secret 名为 cluster-admin-creds,你想查看谁拥有访问它的权限:

$ kubectl who-can get secret cluster-admin-creds -n secure

ROLEBINDING            NAMESPACE       SUBJECT                               TYPE            SA-NAMESPACE
unpriv_sa_binding secure unprivileged-service-account ServiceAccount secure CLUSTERROLEBINDING SUBJECT TYPE SA-NAMESPACE
cluster-admin system:masters Group

输出信息也很一目了然,没什么可说的。提醒一下,该工具只支持查看 create、update 和 delete 这几个访问权限,不支持 use。use 用来将 Pod Security Policy 绑定到相应的 Role。

6. Rakkess

rakkess 与 who-can 类似,可以列出某个账户对所有资源的访问权限,可以通过 krew 来安装。

使用方法也很简单,如果想查看当前用户对所有资源的访问权限,可使用如下命令:

如果想查看某个特定的 Service Account 对所有资源的访问权限,可以使用如下命令:

$ kubectl access-matrix --as system:serviceaccount:kube-ovn:ovn -n kube-ovn

更多用例可以参考官方文档。

7. RBack

rback 用来对 kubectl 的输出结果进行可视化展示,可以输出为 .dot 格式,也可以输出为 .png 或任何格式。

例如:

$ kubectl get sa,roles,rolebindings \
-n monitoring -o json | rback > rback.dot

或者保存为 png:

$ kubectl get sa,roles,rolebindings \
-n monitoring -o json \
| rback | dot -Tpng > rback.png

8. RBAC-View

rbac-view 也可以用来可视化账户与权限之间的关系,但与 rback 不同,它是一个 web 应用,安装方法参考官方文档。

使用方式:

$ kubectl rbac-view
serving RBAC View and http://localhost:8800

在浏览器中打开链接 http://localhost:8800

9. 终极测试

上面提到的所有方法都可以帮助我们快速收集信息,但有时难免会出现误报的情况。想要确认某账户到底有没有相应的权限,可以使用下面提到的终极方法。例如,要想确认 secure namespace 中的 unprivileged-service-account 是否具有 get secret 的权限,可以使用如下的命令:

$ kubectl get secrets \
--as system:serviceaccount:secure:unprivileged-service-account \
-o yaml

10. 模拟攻击

预防攻击最好的方法是模拟攻击,我们可以模拟一个黑客进入其中的某个 Pod,看看能否执行一些不可描述的操作。步骤如下:

  1. 创建一个 Service Account。
$ kubectl create serviceaccount ncc-sa
  1. 创建相应的角色。

  1. 将 Role 与 Service Account 绑定。

  1. 创建一个测试 Pod,serviceAccountName 指定为 ncc-sa

  1. 进入该 Pod

  1. 验证是否具有 get pod 的权限。

    $ kubectl get pod

11. 总结

随着集群环境越来越复杂,RBAC Role 与其相关资源对象之间关系的复杂性也会呈指数级增长。如果 Role 太多,那么运维人员可能很难选择正确的 Role,容易犯错;如果 Role 太少,运维人员可能会被迫选择默认的 Role,这会导致某些 Pod 权限过大。所以我们需要找到一个平衡点,通常的做法是通过 ansibleterraform 将某些部署策略抽象出来变成模板,将 RBAC 策略写到模板中,这样可以大大减轻开发人员的压力。

微信公众号

扫一扫下面的二维码关注微信公众号,在公众号中回复◉加群◉即可加入我们的云原生交流群,群里高手如云,张馆长、阳明大佬、kubesphere 核心贡献者都在哦

这些用来审计 Kubernetes RBAC 策略的方法你都见过吗?的更多相关文章

  1. 附006.Kubernetes RBAC授权

    一 RBAC 1.1 RBAC授权 基于角色的访问控制(RBAC)是一种基于个人用户的角色来管理对计算机或网络资源的访问的方法. RBAC使用rbac.authorization.k8s.io API ...

  2. Kubernetes RBAC授权普通用户对命名空间访问权限

    Kubernetes RBAC授权普通用户对命名空间访问权限 官方文档:https://www.cnblogs.com/xiangsikai/p/11413970.html kind: Role ap ...

  3. 16. kubernetes RBAC

    16. kubernetes RBAC授权插件: Node,ABAC,RBAC,webhock RBAC: role based access contrl 基于角色的授权. 角色:(role)许可( ...

  4. Kubernetes 部署策略详解-转载学习

    Kubernetes 部署策略详解 参考:https://www.qikqiak.com/post/k8s-deployment-strategies/ 在Kubernetes中有几种不同的方式发布应 ...

  5. RBAC类的方法

    rbac类的 方法 authenticate($map,$model='')方法 传入查询用户的条件和用户表的MODEL 返回数组包含用户的信息 saveAccessList($authId=null ...

  6. DRL之:策略梯度方法 (Policy Gradient Methods)

    DRL 教材 Chpater 11 --- 策略梯度方法(Policy Gradient Methods) 前面介绍了很多关于 state or state-action pairs 方面的知识,为了 ...

  7. 深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods)

    深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods) 2018-07-17 16:50:12 Reference:https://www.you ...

  8. 强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods)

    强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods) 学习笔记: Reinforcement Learning: An Introduction, Richa ...

  9. K8S学习笔记之Kubernetes 部署策略详解

    0x00 概述 在Kubernetes中有几种不同的方式发布应用,所以为了让应用在升级期间依然平稳提供服务,选择一个正确的发布策略就非常重要了. 选择正确的部署策略是要依赖于我们的业务需求的,下面我们 ...

随机推荐

  1. vue--组件性别选择器和仿百度搜索栏

    目录 实现原理 性别选择器 仿百度搜索栏 实现原理 主要参考vue官网上的自定义事件,父组件v-bind给子组件传参数,子组件利用props来接受父组件那边传过来的参数.我们还会遇到一个问题,怎么实时 ...

  2. [原创]自动化部署K8S(v1.10.11)集群

          标准运维实现自动化部署K8S集群主要分两步,第一步是部署gse-agent,拱第二步执行部署. 第一步:部署gse-agent.如下: 第二步:部署k8s集群.主要通过作业平台分为5小步执 ...

  3. python函数知识一 函数初始、定义与调用、返回值、参数和函数的好处+菜中菜

    第四章 函数 1.函数初识: def :关键字 -- 定义 函数名:和变量的定义方式一样 (): 用于参数传递,: 形参:函数的定义中()内的是形参 实参:调用的()内是实参 传参:调用时将实参传递给 ...

  4. Jmeter(1):使用TCP取样器与socket接口进行简单通信

    一个小任务:服务器与客户端连接,每次发送50个随机生成的字符,两秒发送一次 失败过太多次,然后昨晚终于跑通了,心情激动,于是清均第一篇博客就诞生了. 之前不了解jmeter,想过单纯用java编写服务 ...

  5. 庖丁解牛Linux内核分析 0x00:《庖丁解牛》

    庖丁解牛  吾生也有涯,而知也无涯 .以有涯随无涯,殆已!已而为知者,殆而已矣!为善无近名,为恶无近刑.缘督以为经,可以保身,可以全生,可以养亲,可以尽年. 庖丁为文惠君解牛,手之所触,肩之所倚,足之 ...

  6. [翻译] .NET Core 3.0 Preview 7 发布

    原文: Announcing .NET Core 3.0 Preview 7 今天,我们宣布推出 .NET Core 3.0 Preview 7 .我们的工作已经从创建新功能过渡到打磨版本.预计剩余的 ...

  7. win10虚拟机搭建Hadoop集群(已完结)

    1 在虚拟机安装 Ubuntu 2 安装网络工具 Ubuntu最小化安装没有 ifconfig命令 sudo apt-get install net-tools 3 Ubuntu修改网卡名字 修改网卡 ...

  8. es6,@import一直报错 Can't resolve。。

    最近在项目中新增了一个按钮组的组件页面,但是在其他页面引入时,一直报错 引入方式:

  9. 二进制文件安装安装flannel

    二进制文件安装安装flannel overlay网络简介 覆盖网络就是应用层网络,它是面向应用层的,不考虑或很少考虑网络层,物理层的问题. 详细说来,覆盖网络是指建立在另一个网络上的网络.该网络中的结 ...

  10. Handler 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...