写点什么

API-server 安全机制完全解读:认证方式、授权方式、准入控制

2020 年 5 月 18 日

API-server安全机制完全解读:认证方式、授权方式、准入控制

目录

  • API-server 的作用

  • API-server 提供的安全机制

  • 认证方式之——TLS

  • 授权方式之——node

  • 授权方式之——RBAC

  • 准入控制之——NodeRestriction

  • 自定义准入插件


API-server 的作用

在 Kubernetes 集群中 API-server 的作用有以下几点:


  • 提供了集群管理的 REST API 接口

  • 提供其他模块之间的数据交互和通信的枢纽

  • 是资源配额控制的入口

  • 提供一定的集群安全机制


通俗来讲,API-server 就是整个集群的入口,任何用户和程序对集群资源的增删改查操作都必须经过 API-server。为了保证集群的安全,API-server 提供了完备的安全机制。


API-server 提供的安全机制

API-server 的本质就是一个 web 服务器,底层代码是基于 go-restful 这个 web 框架搭建的。传统的 web 服务器在安全方面一般都会提供认证/授权机制,以过滤器的方式实现。在 API-server 中也以类似于过滤器的方式提供了认证、授权机制,不同的是 API-server 还提供了准入检查。下面一一讲解。


认证(Authentication),识别用户身份。认证的方式有很多,比如:HTTP base,HTTP token,TLS,Service Account,OpenID Connect 等。高版本的 kubernetes 默认的认证方式是 TLS。在 TLS 认证方案中,每个用户都拥有自己的 X.509 客户端证书,API 服务器通过配置的证书颁发机构(CA)验证客户端证书。


授权(Authorization),识别是否有相应操作权利。授权者,通过组合属性(用户属性,资源属性,实体)的策略向用户授予访问权限。授权的方式也有很多,比如:AlwaysDeny、AlwaysAllow、ABAC、RBAC、node 等,高版本的 kubernetes 默认的授权方式是 RBAC 和 node。


准入(Admission Controller),判断你的操作是否符合集群的要求,这是一种更灵活的管控机制,用户还可以根据自己的需求定义准入插件来管理集群。kubernetes 中将准入模块分为三种,validating(验证型),mutating(修改型)以及两者兼有,准入的默认配置是 NodeRestriction。


我理解的准入和授权的区别主要有以下几点:


  • 运行时机不同。认证/授权模块相当于是 web 开发中的 filter,是针对请求头和证书进行分析操作,运行在具体 handle 处理逻辑之前,而准入模块可以操作具体的请求体,是在具体的处理逻辑中。

  • 管控范围不同。授权模块只管控用户有没有操作的权限,具体操作的细节并不关注。准入模块可以管控用户申请的资源大小(LimitRanger),可以细粒度地划分用户权限(NodeRestriction),可以检查用户创建的命名空间是否存在(NamespaceLifecycle)等等。

  • 运行逻辑不同。准入模块之间是逻辑与的关系,设定之后用户的任何请求必须满足所有的准入检查,如果一个插件不满足就会拒绝请求。认证/授权模块之间是逻辑或的关系,只要满足一个请求就可以通过。



认证方式之——TLS

TLS 是安全传输层协议,包括两部分:TLS 记录协议和 TLS 握手协议。TLS 记录协议主要保证传输过程中信息传输的完整性和私密性,这一部分通过协商后的密钥来加密数据。TLS 握手协议主要是为了认证对方的身份、协商密钥。在握手协议中主要涉及到身份认证,下面结合 Kubernetes 说明。


什么是证书

常见的证书格式是 X509 格式。格式如下:



这个证书里面主要包含了主体的公钥信息,主体的身份信息,证书授权中心,签名信息等等,观察图可知,这个用户组就是 system:nodes,用户名是 system.node.slave1,授权中心是 kubernetes,当需要验证这个证书的真伪时,就需要使用证书授权中心的公钥去解析签名(因为签名是由证书授权中心对证书信息经过消息摘要再使用私钥加密得到的),当解析出来的信息和证书的信息匹配时就认证通过了。


证书授权中心(Certificate Authority)可以自建也可以依赖于第三方机构,本质就是一对密钥,对认证过的身份信息经过私钥加密,公钥公开,任何用户都可以使用公钥解析证书得到被认证者的身份信息,这样就达到了身份验证的目的。


API-server 与 kubelet-client 的证书验证

为了方便用户访问 kube-apiserver,推荐配置方式是采用 kubeconfig 文件。这个配置文件里面描述了集群、上下文和用户信息。我们来看 kubelet 默认的 kubeconfig 文件。


首先 kubelet 的 kubeconfig 如下所示:



上图 users.user.client-certificate 字段就是用户的证书地址,这个证书由 kubernetes 签发,我们使用 kubernetes 的公钥来验证这个文件。



结果显示验证成功,验证成功后得到用户的身份信息。在我们自建 CA 时,一定要保存好 CA 的私钥。如果私钥丢失那么攻击者可以制作证书,从而认证通过。


授权方式之——node

节点授权方式是专门为 kubelet 发出的请求的一种授权方式。从上小节可以看出 kubelet 经过认证以后得到的用户组是 system:nodes,用户名是 system:node:slave1,这个满足节点授权的用户名格式 system:node:<nodename>,于是这个用户被赋予以下的权限。



可见这个节点授权赋予每个节点的权力很大。可以对整个集群的 pod、node 等资源进行操作。如果没有设置准入控制 NodeRestriction,那么节点授权是很危险的。


授权方式之——RBAC

RBAC 是一种基于角色的授权方式,这里涉及到两类资源,一类是 RoleBinding、ClusterRoleBinding,另一类是 Role、ClusterRole,角色是对用户拥有权利的抽象,角色绑定是将角色绑定到用户(user、group 或者 service account)。在使用 RBAC 创建自己的角色时,要秉持最小权限原则,防止操作范围过大而影响集群安全。



在 Kubernetes 中已经默认建立了很多角色,在创建自己的角色之前可以考虑默认的角色。


准入控制之——NodeRestriction

这个插件的作用是限制每一个 kubelet 只能操作自己 node 的资源。在集群部署中,最好设置 NodeRestriction,如果没有设置这个准入插件不法分子可以通过攻克一个子节点获得 kubelet 的证书和密钥,进而远程控制整个集群的资源。


自定义准入插件

Kubernetes 准入模块强大的地方在于提供了 External Admission Webhook,可以基于这个功能自定义准入插件。这里涉及到两个特殊的准入控制器:


MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。这两个控制器将发送准入请求到外部的 HTTP 回调服务并接收一个准入响应。如果启用了这两个准入控制器,Kubernetes 管理员可以在集群中创建和配置一个 admission webhook。API server 发送一个 AdmissionReview 的 json 数据到 webhook,其中主要包含一个 AdmissionRequest 的请求,以及需要处理的 kubernetes 资源的详细信息。webhook 在接收到该请求之后会根据自定义逻辑进行处理,并返回处理结果 AdmissionResponse。


自定义准入插件的示例代码可以在 github 中找到,这个项目最主要的就是 main.go 文件。


下面是 main.go 文件中的 admit 代码:


// 验证的主要逻辑func admit(data []byte) *v1alpha1.AdmissionReviewStatus {    ar := v1alpha1.AdmissionReview{}    if err := json.Unmarshal(data, &ar); err != nil {        glog.Error(err)        return nil    }    podResource := metav1.GroupVersionResource{Group: "", Version: "v1", Resource: "pods"}    if ar.Spec.Resource != podResource {        glog.Errorf("expect resource to be %s", podResource)        return nil    }    raw := ar.Spec.Object.Raw    pod := v1.Pod{}    if err := json.Unmarshal(raw, &pod); err != nil {        glog.Error(err)        return nil    }    reviewStatus := v1alpha1.AdmissionReviewStatus{}    for _, container := range pod.Spec.Containers {        if !strings.Contains(container.Image, "gcr.io") {            reviewStatus.Allowed = false            reviewStatus.Result = &metav1.Status{                Reason: "can only pull image from grc.io",            }            return &reviewStatus        }    }    reviewStatus.Allowed = true    return &reviewStatus}
复制代码


这里面核心的结构体就是 AdmissionReview。AdmissionReview 里面的 AdmissionRequest 中封装了可用于逻辑判断的所有请求信息,用户可以根据自己的要求自定义验证逻辑。当创建好自己的镜像之后按照项目中的步骤部署运行。


2020 年 5 月 18 日 18:03312

评论

发布
暂无评论
发现更多内容

大厂面试:求解集装箱港口翻箱问题的最短路径

华为云开发者社区

算法 路径 模型

数据库的两个好帮手:pagehack和pg_xlogdump

华为云开发者社区

数据库 故障 GaussDB pagehack pg_xlogdump

读书总结2020

IT民工大叔

#读书

《TestNG》源码学习笔记

吴大山

可能是Java 8 Optional最佳实践

ES_her0

28天写作

为什么 Python 的 f-string 可以连接字符串与数字?

Python猫

Python 开源 编程语言 后端 C语言

Spring Boot(一):入门篇

海鸥云

spring Boot Starter

SICP 习题答案1.1 - 1.5

十元

程序员如何技术划水,Android项目开发如何设计整体架构?Android岗

欢喜学安卓

android 程序员 面试 移动开发

LeetCode题解:53. 最大子序和,动态规划,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

Kafka.02 - Topic 介绍

insight

kafka 2月春节不断更

Elasticsearch filter vs. query 对比

escray

elastic 七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试 2月春节不断更

【STM32】CubeMX+HAL 点亮 LED

AXYZdong

硬件 stm32 2月春节不断更

安卓软件开发!Android线程池基础入门和简单实践以及使用技巧,面试真题解析

欢喜学安卓

android 程序员 面试 移动开发

产品经理问我:手动创建线程不香吗,为什么非要用线程池呢?

Java鱼仔

线程池 Java 8

我要看 SICP 了!

十元

构建万物可信互联的基石,带你深度剖析区块链跨链的关键技术,满满是干货!

华为云开发者社区

区块链 智能合约 云原生 跨链技术 分布式账本技术

诊所数字化:搭建网络路径的信息铺设策略

boshi

数字化转型 医疗 七日更 28天写作

著名的Java并发编程大师都这么说了,你还不知道伪共享么!

看点代码再上班

Java 后端 后端开发

熟练HTML5+CSS3,每天复习一遍

魔王哪吒

面试 前端 28天写作 2月春节不断更

在gradle中构建java项目

程序那些事

Java maven Gradle 程序那些事 构建工具

Golang代码测试:一点到面用测试驱动开发

华为云开发者社区

go golang 测试 TDD 代码

《经济学人》2021年2月20日刊精彩文章导读及资源下载

wbliu85

工作日志2-19

一锅水端平

日记 2021年2月20日(周六)

Changing Lin

2月春节不断更

重大更新!一文了解京东通用目标重识别开源库FastReID V1.0

京东科技开发者

AI 监控

ZEGO全新语音聊天解决方案,4步搭建爆火的语音聊天室

ZEGO即构

AI窥人(三):你想靠AI实现永生吗?

脑极体

都在说云原生,它的技术图谱你真的了解吗?

浪潮云

云原生

week12 作业

zbest

go get下载包失败问题

happlyfox

golang Proxy 28天写作

API-server安全机制完全解读:认证方式、授权方式、准入控制-InfoQ