033.Kubernetes集群安全

一 Kubernetes集群安全

1.1 安全机制

Kubernetes通过一系列机制来实现集群的安全控制,其中包括API Server的认证授权、准入控制机制及保护敏感信息的Secret机制等。集群的安全性主要有如下目标:
  1. 保证容器与其所在宿主机的隔离。
  2. 限制容器给基础设施或其他容器带来的干扰。
  3. 最小权限原则—合理限制所有组件的权限, 确保组件只执行它被授权的行为, 通过限制单个组件的能力来限制它的权限范围。
  4. 明确组件间边界的划分。
  5. 划分普通用户和管理员的角色。
  6. 在必要时允许将管理员权限赋给普通用户。
  7. 允许拥有Secret数据(Keys、 Certs、 Passwords) 的应用在集群中运行。

二 API Server认证管理

2.1 认证安全

Kubernetes集群中所有资源的访问和变更都是通过Kubernetes API Server的RESTAPI来实现的,因此集群安全的关键点就在于如何识别并认证客户端身份(Authentication),以及随后访问权限的授权(Authorization)环节。
Kubernetes集群提供了3种级别的客户端身份认证方式。
  1. HTTPS证书认证:此方式最严格,基于CA根证书签名的双向数字证书认证方式。
  2. HTTP Token认证:通过一个Token来识别合法用户。
  3. 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中认证大概包含下面几个步骤:
clipboard

  1. HTTPS通信双方的服务器端向CA机构申请证书,CA机构是可信的第三方机构,它可以是一个公认的权威企业,也可以是企业自身。企业内部系统一般都用企业自身的认证系统。CA机构下发根证书、服务端证书及私钥给申请者。
  2. HTTPS通信双方的客户端向CA机构申请证书,CA机构下发根证书、客户端证书及私钥给申请者。
  3. 客户端向服务器端发起请求,服务端下发服务端证书给客户端。客户端接收到证书后,通过私钥解密证书,并利用服务器端证书中的公钥认证证书信息比较证书里的消息,例如,比较域名和公钥与服务器刚刚发送的相关消息是否一致,如果一致,则客户端认可这个服务器的合法身份。
  4. 客户端发送客户端证书给服务器端,服务端在接收到证书后,通过私钥解密证书,获得客户端证书公钥,并用该公钥认证证书信息,确认客户端是否合法。
  5. 客户端通过随机密钥加密信息,并发送加密后的信息给服务端。在服务器端和客户端协商好加密方案后,客户端会产生一个随机的密钥,客户端通过协商好的加密方案加密该随机密钥,并发送该随机密钥到服务器端。服务器端接收这个密钥后,双方通信的所有内容都通过该随机密钥加密。

上述是双向认证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”设置):
  1. AlwaysDeny:表示拒绝所有请求,一般用于测试。
  2. AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
  3. ABAC(Attribute-BasedAccessControl):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制。
  4. Webhook:通过调用外部REST服务对用户进行授权。
  5. RBAC:Role-BasedAccessControl,基于角色的访问控制。
  6. 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授权》

033.Kubernetes集群安全

全文结束