对Kubernetes RBAC授权防御&攻击的部分思考
写在前面 不久前看到一篇对Kubernetes授权管理的文章,笔者而后进行一些实验和思考,因此诞生了这篇学习笔记。本文章思路未必贴合实际应用场景,有概念错误的地方还望多多指正。 首先笔者对于Kubernetes用户的授权分为两个抽象主体:对「基础设施」的权限授予和对「服务」的权限授予。 分类讨论 0x01-基础设施 「基础设施」的权限,理想情况下按照集群结构划分: master节点使用admin用户账户权限,意即管理员权限 node节点使用普通用户权限,普通用户权限仅能对集群中的部分资源控制,或者是对某个namespcace中的资源进行控制 0x02-服务 什么又叫做对「服务」进行划分呢?云计算的初衷是优雅地调配庞大规模的服务群,那么运维人员就需要对A、B、C…这些服务(Service)能够操纵集群权限这个能力进行考量,假如Service A由三台nginx容器构成,可能就不需要什么集群服务的资源。对于B服务而言,其定位是用来监控集群主机健康状态的,所以就需要很强的「CURD」权限,起码是对「Pod」、「Deployment」有管理权限。 在「Kubernetes」中,每个服务容器都会被「kubelet」下发一个默认的「ServiceAccount」账户(后文简称SA),而运维人员可以指定服务容器注入哪个SA账户。这意味着运维人员可以将不同SA账户注入给各类服务容器,来达到各类服务(A、B、C)权限细粒度化。 0x03-归根到底 「基础设施」和「服务」的权限授予有相同之处,但又不完全相同。相同的地方在于概念,都是为了控制对集群资源操纵的能力,这一过程在「Kubernetes」中叫做「授权(Authoriazation)」,可以参考下图;不同的地方在于控制单元,基础设施的权限是以「用户账户(User Account)」的权限为单位的,而服务的权限是以「SA账户(ServiceAccount)」为单位划分的。 那么,有没有办法来优雅地控制对这两种权限授予方式的统一呢?答案很显然是有,而且不止一种。这里摘取一种比较好的做法:通过「ClusterRole」分发权限。 例如管理员事先建立「Pod-read-Rule」、「Pod-Write-Rule」规则,分别用来制约对Pod容器可读、可写这两种「操作」,当然集群的资源可不止有Pod容器,我们可以通过「kubectl api-resources」例举哪些资源可以被「ClusterRole」约束。 而后,通过「RoleBinding」或者「ClusterBinding」的方式将这两个「ClusterRole」分发给不同的「User Account」或者「ServiceAccount」,相当于是把锅碗瓢盆给到不同的角色。 假设一个场景,当「User Account A」需要拥有所有Pod的可读权限,那么管理员(kubernetes admin)就通过「RoleBinding」的形式将「Pod-read-Rule」绑定给「User Account A」;当「User Account A」再想要要所有Pod的可写权限时,以相同的「RoleBinding」方式将「Pod-Write-Rule」绑定给「User Account A」即可。 最终,我们创建一个理想化的场景:把集群内所有可利用资源(api-resources)的「CURD」操作分别建立为不同的「ClusterRole」,在创建「Service Account」与「User Account」时赋予它们最小权限,指定最少范围的「namespace」,最好只作用于default namespcace。而后当「SA」或者「UA」需要对应权限时,管理员再经过审核制「RoleBinding」,分配「ClusterRole」给这些「SA」或者「UA」,而不是在初始化时就把权限塞满。 实践 下面以两个实践为例,理解前文提到的权限分发思路。表格为实验拓扑:一台Centos7.x作为Master节点,剩下两台作为Node节点 主机 IP地址 内核版本 用户账户 k8s-master 192.168.56.80 3.10.0-1160.el7.x86_64 kubernetes-admin k8s-node1 192.168.56.81 3.10.0-1160.el7.x86_64 userA k8s-node2 192.168.56.82 3.10.0-1160.el7.x86_64 userB 实践场景1-使用UserAccount master节点使用kubernetes-admin用户进行管理,其他两个node节点使用userA、userB用户进行管理,且需要满足的条件: kubernetes-admin具有对集群操纵的全部权限 userA用户仅拥有对tenantA命名空间的Pod容器完全操作权限 userB用户仅拥有对tenantB命名空间的Pod容器完全操作权限 分析:由于「master」节点的用户配置文件「/etc/kubernetes/admin.conf」默认为kubernetes-admin权限,所以我们无需关心,只需满足UserA、B的需求。 第一步:建立两个Kubernetes User Account分别为userA、userB,参考文章:k8s创建用户账号——User Account - fat_girl_spring - 博客园 (cnblogs.com)。完整的创建过程如下,以相同的方式创建两个用户即可 [root@k8s-master tenantA]# (umask 077;openssl genrsa -out userA.
Read more...