这些用来审计 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 来安装:
安装 krew。参考 https://github.com/kubernetes-sigs/krew/
安装
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,看看能否执行一些不可描述的操作。步骤如下:
- 创建一个 Service Account。
$ kubectl create serviceaccount ncc-sa
- 创建相应的角色。
- 将 Role 与 Service Account 绑定。
- 创建一个测试 Pod,serviceAccountName 指定为
ncc-sa
。
- 进入该 Pod
验证是否具有
get pod
的权限。$ kubectl get pod
11. 总结
随着集群环境越来越复杂,RBAC Role 与其相关资源对象之间关系的复杂性也会呈指数级增长。如果 Role 太多,那么运维人员可能很难选择正确的 Role,容易犯错;如果 Role 太少,运维人员可能会被迫选择默认的 Role,这会导致某些 Pod 权限过大。所以我们需要找到一个平衡点,通常的做法是通过 ansible 或 terraform 将某些部署策略抽象出来变成模板,将 RBAC 策略写到模板中,这样可以大大减轻开发人员的压力。
微信公众号
扫一扫下面的二维码关注微信公众号,在公众号中回复◉加群◉即可加入我们的云原生交流群,群里高手如云,张馆长、阳明大佬、kubesphere 核心贡献者都在哦
这些用来审计 Kubernetes RBAC 策略的方法你都见过吗?的更多相关文章
- 附006.Kubernetes RBAC授权
一 RBAC 1.1 RBAC授权 基于角色的访问控制(RBAC)是一种基于个人用户的角色来管理对计算机或网络资源的访问的方法. RBAC使用rbac.authorization.k8s.io API ...
- Kubernetes RBAC授权普通用户对命名空间访问权限
Kubernetes RBAC授权普通用户对命名空间访问权限 官方文档:https://www.cnblogs.com/xiangsikai/p/11413970.html kind: Role ap ...
- 16. kubernetes RBAC
16. kubernetes RBAC授权插件: Node,ABAC,RBAC,webhock RBAC: role based access contrl 基于角色的授权. 角色:(role)许可( ...
- Kubernetes 部署策略详解-转载学习
Kubernetes 部署策略详解 参考:https://www.qikqiak.com/post/k8s-deployment-strategies/ 在Kubernetes中有几种不同的方式发布应 ...
- RBAC类的方法
rbac类的 方法 authenticate($map,$model='')方法 传入查询用户的条件和用户表的MODEL 返回数组包含用户的信息 saveAccessList($authId=null ...
- DRL之:策略梯度方法 (Policy Gradient Methods)
DRL 教材 Chpater 11 --- 策略梯度方法(Policy Gradient Methods) 前面介绍了很多关于 state or state-action pairs 方面的知识,为了 ...
- 深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods)
深度学习课程笔记(十三)深度强化学习 --- 策略梯度方法(Policy Gradient Methods) 2018-07-17 16:50:12 Reference:https://www.you ...
- 强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods)
强化学习读书笔记 - 13 - 策略梯度方法(Policy Gradient Methods) 学习笔记: Reinforcement Learning: An Introduction, Richa ...
- K8S学习笔记之Kubernetes 部署策略详解
0x00 概述 在Kubernetes中有几种不同的方式发布应用,所以为了让应用在升级期间依然平稳提供服务,选择一个正确的发布策略就非常重要了. 选择正确的部署策略是要依赖于我们的业务需求的,下面我们 ...
随机推荐
- 前端经常碰到的小知识点-----js篇
一 js 1.可视区宽和高 ① document.documentElement.clientWidth //可视区的宽度 document.documentElement.clientHei ...
- QRowTable表格控件(二)-红涨绿跌
目录 一.开心一刻 二.概述 三.效果展示 四.任务需求 五.指定列排序 六.排序 七.列对其方式 八.相关文章 原文链接:QRowTable表格控件(二)-红涨绿跌 一.开心一刻 一天,五娃和六娃去 ...
- Postgresql_fdw
Postgresql_fdw 测试环境 Ubuntu 16.04 LTS云主机2台,主机名为pg1(192.168.0.34)和pg2(192.168.0.39). 安装postgresql 下面这个 ...
- Cocos2d-x 3.x 学习笔记(三):Scheduler Timer 调度与定时
1. 概述 Cocos2d-x 的 Scheduler 离不开 Timer.Timer 类是定时器,用来规定一个回调函数应该在何时被触发.Timer 封装了已运行时间.重复次数.已执行次数.延迟秒数 ...
- re模块:模式匹配与正则表达式
一.用正则表达式查找文本模式 正则表达式,简称regex,是文本模式的描述方法.比如\d是一个正则表达式,用于表示一位0~9的数字.在一个模式后面加上花括号包围的数字n(如{n}),表示匹配这个模式n ...
- redis分布式锁的问题和解决
分布式锁 在分布式环境中,为了保证业务数据的正常访问,防止出现重复请求的问题,会使用分布式锁来阻拦后续请求.具体伪代码如下: public void doSomething(String userId ...
- NOIP2018提高/普及成绩
明天就要出了,不忍看到自己爆零,现在很慌. 大家都考的如何呢?欢迎留言自己的分数或预估分数.
- 自实现input上传指定文件到服务器
遇到问题,解决问题,记录问题,成长就是一步一步走出来的. 一.添加 input 标签 我的工作中遇到了,需要上传pdf文件到服务器的需求,而且只能上传pdf文件,accept指定了 pdf 类型. & ...
- android在style中使用自定义属性 error: style attribute not found.
异常: Error:(128, 5) error: style attribute 'com.honghui0531.prebiotics.view:attr/item_right_icon_src' ...
- FAIRR
FAIRR 在进行一项工作时需要注意学习.应用和改进已有信息和成果,可参考FAIRR原则: Find existing info and result, Add to and Improve it, ...