一 Kubernetes 集群安全
1.1 安全机制
Kubernetes 通过一系列机制来实现集群的安全控制, 其中包括 API Server 的认证授权, 准入控制机制及保护敏感信息的 Secret 机制等. 集群的安全性主要有如下目标:
保证容器与其所在宿主机的隔离.
限制容器给基础设施或其他容器带来的干扰.
最小权限原则 - 合理限制所有组件的权限, 确保组件只执行它被授权的行为, 通过限制单个组件的能力来限制它的权限范围.
明确组件间边界的划分.
划分普通用户和管理员的角色.
在必要时允许将管理员权限赋给普通用户.
允许拥有 Secret 数据(Keys, Certs, Passwords) 的应用在集群中运行.
二 API Server 认证管理
2.1 认证安全
Kubernetes 集群中所有资源的访问和变更都是通过 Kubernetes API Server 的 RESTAPI 来实现的, 因此集群安全的关键点就在于如何识别并认证客户端身份 (Authentication), 以及随后访问权限的授权(Authorization) 环节.
Kubernetes 集群提供了 3 种级别的客户端身份认证方式.
HTTPS 证书认证: 此方式最严格, 基于 CA 根证书签名的双向数字证书认证方式.
HTTP Token 认证: 通过一个 Token 来识别合法用户.
HTTP Base 认证: 通过用户名 + 密码的方式认证.
2.2 HTTPS 认证原理
此方式需要有一个 CA 证书, CA 是 PKI 系统中通信双方都信任的实体, 被称为可信第三方(TrustedThirdParty,TTP).CA 作为可信第三方的重要条件之一就是 CA 的行为具有非否认性. 作为第三方而不是简单的上级, 就必须能让信任者有追究自己责任的能力.
CA 通过证书证实他人的公钥信息, 证书上有 CA 的签名. 用户如果因为信任证书而有了损失, 则证书可以作为有效的证据用于追究 CA 的法律责任. 正是因为 CA 承担责任的承诺, 所以 CA 也被称为可信第三方.
在很多情况下, CA 与用户是相互独立的实体, CA 作为服务提供方, 有可能因为服务质量问题 (例如, 发布的公钥数据有错误) 而给用户带来损失. 在证书中绑定了公钥数据和相应私钥拥有者的身份信息, 并带有 CA 的数字签名; 在证书中也包含了 CA 的名称, 以便于依赖方找到 CA 的公钥, 验证证书上的数字签名.
CA 认证涉及诸多概念, 比如根证书, 自签名证书, 密钥, 私钥, 加密算法及 HTTPS 等.
如下大致为 SSL 协议的流程, 在 Kubernetes CA 中认证大概包含下面几个步骤:
HTTPS 通信双方的服务器端向 CA 机构申请证书, CA 机构是可信的第三方机构, 它可以是一个公认的权威企业, 也可以是企业自身. 企业内部系统一般都用企业自身的认证系统. CA 机构下发根证书, 服务端证书及私钥给申请者.
HTTPS 通信双方的客户端向 CA 机构申请证书, CA 机构下发根证书, 客户端证书及私钥给申请者.
客户端向服务器端发起请求, 服务端下发服务端证书给客户端. 客户端接收到证书后, 通过私钥解密证书, 并利用服务器端证书中的公钥认证证书信息比较证书里的消息, 例如, 比较域名和公钥与服务器刚刚发送的相关消息是否一致, 如果一致, 则客户端认可这个服务器的合法身份.
客户端发送客户端证书给服务器端, 服务端在接收到证书后, 通过私钥解密证书, 获得客户端证书公钥, 并用该公钥认证证书信息, 确认客户端是否合法.
客户端通过随机密钥加密信息, 并发送加密后的信息给服务端. 在服务器端和客户端协商好加密方案后, 客户端会产生一个随机的密钥, 客户端通过协商好的加密方案加密该随机密钥, 并发送该随机密钥到服务器端. 服务器端接收这个密钥后, 双方通信的所有内容都通过该随机密钥加密.
上述是双向认证 SSL 协议的具体通信过程, 这种情况要求服务器和用户双方都有证书. 单向认证 SSL 协议则不需要客户端拥有 CA 证书, 对于上面的步骤, 只需将服务器端验证客户证书的过程去掉, 之后协商对称密码方案和对称通话密钥时, 服务器发送给客户的密码没被加密即可.
2.3 HTTP Token 认证原理
HTTP Token 的认证是用一个很长的特殊编码方式的并且难以被模仿的字符串 - Token 来表明客户身份的一种方式. 在通常情况下, Token 是一个很复杂的字符串, 比如我们用私钥签名一个字符串后的数据就可以被当作一个 Token. 此外, 每个 Token 对应一个用户名, 存储在 API Server 能访问的一个文件中. 当客户端发起 API 调用请求时, 需要在 HTTP Header 里放入 Token, 这样一来, API Server 就能识别合法用户和非法用户了.
2.4 HTTP Base 认证原理
通常, HTTP 是无状态的, 浏览器和 web 服务器之间可以通过 Cookie 来进行身份识别. 桌面应用程序 (比如新浪桌面客户端, SkyDrive 客户端, 命令行程序) 一般不会使用 Cookie, 若需要与 Web 服务器之间通信并且进行认证. 则需要使用 HTTP Base 认证, 这种认证方式是把 "用户名 + 冒号 + 密码" 用 BASE64 算法进行编码后的字符串放在 HTTP Request 中的 Header Authorization 域里发送给服务端, 服务端在收到后进行解码, 获取用户名及密码, 然后进行用户身份鉴权.
三 API Server 授权管理
3.1 授权管理概述
当客户端发起 API Server 调用时, API Server 内部要先进行用户认证, 然后执行用户授权流程, 即通过授权策略来决定一个 API 调用是否合法. 对合法用户进行授权并且随后在用户访问时进行鉴权, 是权限与安全系统的重要一环.
授权就是授予不同的用户不同的访问权限.
API Server 目前支持以下几种授权策略(通过 API Server 的启动参数 "--authorization-mode" 设置):
AlwaysDeny: 表示拒绝所有请求, 一般用于测试.
AlwaysAllow: 允许接收所有请求, 如果集群不需要授权流程, 则可以采用该策略, 这也是 Kubernetes 的默认配置.
ABAC(Attribute-BasedAccessControl): 基于属性的访问控制, 表示使用用户配置的授权规则对用户请求进行匹配和控制.
Webhook: 通过调用外部 REST 服务对用户进行授权.
RBAC:Role-BasedAccessControl, 基于角色的访问控制.
Node: 是一种专用模式, 用于对 kubelet 发出的请求进行访问控制.
API Server 在接收到请求后, 会读取该请求中的数据, 生成一个访问策略对象, 如果在该请求中不带某些属性(如 Namespace), 则这些属性的值将根据属性类型的不同, 设置不同的默认值(例如, 为字符串类型的属性设置一个空字符串; 为布尔类型的属性设置 false; 为数值类型的属性设置 0). 然后将这个访问策略对象和授权策略文件中的所有访问策略对象逐条匹配, 如果至少有一个策略对象被匹配, 则该请求被鉴权通过, 否则终止 API 调用流程, 并返回客户端的错误调用码.
四 ABAC 授权模式
4.1 ABAC 授权策略
在 API Server 启用 ABAC 模式时, 需要指定授权策略文件的路径和名称(--authorization-policy-file=SOME_FILENAME), 授权策略文件里的每一行都以一个 Map 类型的 JSON 对象进行设置, 这被称为 "访问策略对象". 通过设置访问策略对象中的 apiVersion,kind,spec 属性来确定具体的授权策略.
其中, apiVersion 当前版本为 abac.authorization.kubernetes.io/v1beta1;kind 被设置为 Policy;spec 指详细的策略设置, 包括主题属性, 资源属性, 非资源属性这三个字段.
主体属性
user(用户名): 字符串类型, 该字符串类型的用户名来源于 Token 文件 (--token-auth-file 参数设置的文件) 或基本认证文件中用户名称段的值.
group(用户组): 在被设置为 "system:authenticated" 时表示匹配所有已认证的请求, 在被设置为 "system:unauthenticated" 时表示匹配所有未认证的请求.
资源属性
API Group(API 组): 字符串类型, 表明匹配哪些 API Group, 例如 extensions 或 *(表示匹配所有 API Group).
namespace(命名空间): 字符串类型, 表明该策略允许访问某个 Namespace 的资源, 例如 kube-system 或 *(表示匹配所有 Namespace).
resource(资源): 字符串类型, API 资源对象, 例如 pods 或 *(表示匹配所有资源对象).
非资源属性
nonResourcePath(非资源对象类路径): 非资源对象类的 URL 路径, 例如 / version 或 / apis,* 表示匹配所有非资源对象类的请求路径, 也可以设置为子路径,/foo/* 表示匹配所有 / foo 路径下的所有子路径.
readonly(只读标识): 布尔类型, 当它的值为 true 时, 表明仅允许 GET 请求通过.
4.2 ABAC 授权算法
API Server 进行 ABAC 授权的算法为: 在 API Server 收到请求之后, 首先识别出请求携带的策略对象的属性, 然后根据在策略文件中定义的策略对这些属性进行逐条匹配, 以判定是否允许授权. 如果有至少一条匹配成功, 那么这个请求就通过了授权(不过还是可能在后续其他授权校验中失败).
常见的策略配置如下:
要允许所有认证用户做某件事, 可以写一个策略, 将 group 属性设置为 system:authenticated.
要允许所有未认证用户做某件事, 可以把策略的 group 属性设置为 system:unauthenticated.
要允许一个用户做任何事, 将策略的 API Group,namespace,resource 和 nonResourcePath 属性设置为 "*" 即可.
4.3 使用 kubectl 授权机制
kubectl 使用 API Server 的 / API 和 / apis 端点来获取版本信息. 要验证 kubectlcreate/update 命令发送给服务器的对象, kubectl 需要向 OpenAPI 进行查询, 对应的 URL 路径为 / openapi/v2.
当使用 ABAC 授权模式时, 下列特殊资源必须显式地通过 nonResourcePath 属性进行设置:
API 版本协商过程中的 / API,/API/*,/apis, 和 / apis/*.
使用 kubectlversion 命令从服务器获取版本时的 / version.
create/update 操作过程中的 / swaggerapi/*.
在使用 kubectl 操作时, 如果需要查看发送到 API Server 的 HTTP 请求, 则可以将日志级别设置为 8.
4.4 常见 ABAC 示例
更多 ABAC 参考:《附 007.Kubernetes ABAC 授权》.
五 RBAC 授权模式
见《附 006.Kubernetes RBAC 授权》
来源: https://www.cnblogs.com/itzgr/p/12524470.html