KubeCon2018 -- Secret Management Deep Dive

  在刚刚过去的Kubecon2018上,诸多大厂的安全专家为我们带来了很多kubernetes安全相关的精彩分享,议题包含集群权限控制,安全配置,漏洞分析等多个方向,其中secret management作为一个热点topic,有多位演讲者对其相关工作做了详尽分析。

什么是Secret?

  连接是一个应用系统的灵魂,无论是人机或是机机之间的通讯,都会包含一些敏感信息用于我们常说的认证和鉴权,比如用户相关的用户名密码,配置文件中的数据库连接凭证,一个请求的API token,TLS证书等,这些都属于Secret的范畴。Google的安全工程师给了Secret一个很好的定义:

Credentials, configurations, API keys, and other small bits of information needed by applications at build or run time

用户遇到的问题

  • 诸如数据库密码等敏感信息写死在源码或未经保护的配置文件中
  • 管理员密码或证书密钥被开发者push到github上造成泄露
  • 由于不完备的权限控制造成一个未授权用户看到了授权域外的敏感信息
  • 一个即将离职的开发者仍旧可以使用之前颁发的证书凭证访问获取业务系统敏感文件
     

而一个完备的密文管理系统正是帮助我们解决诸如此类信息泄露或滥用问题的关键。

Secret Management

 基于上述问题Google大牛给出了密文管理的五大需求:

  • 身份认证:读取secret需要难以复制的身份并遵从权限最小化原则
  • 审计:对secret读写的审计
  • 加密:保证secret加密落盘
  • 轮转:当密文或加密密钥存在泄露风险时具备对其轮转的能力
  • 隔离:secret管控组件保证隔离性

image.png

  对于k8s应用场景下用户数据的加解密,Google大神给出的推荐方式是分层加密。如果我是一个云端的应用用户,我可以把自己用于加解密的密钥放置在云上的KMS服务存储中,而通过KMS服务暴露的REST接口,实现应用敏感信息与存储之间通讯过程中的加解密。

image.png

  可以想到,采用这种分层架构的加密方案会有如下优点:

  1)加密密钥(Key)是整个业务应用安全的核心,从上面Google的插图中可以看到,面对一个经过加密的业务敏感数据,即使它经过异常强大的加密算法保护,攻击者仍旧可以通过泄露的密钥轻易获取数据。(例如给密钥管理员下药。。用一个5刀的扳手对其严刑逼供。。。)而利用密钥管理服务,终端应用用户无需具备专业的安全领域知识即可让其业务应用满足密钥的权限控制、审计、轮转等关键安全合规要求。
  2)减轻了管控集群的业务处理压力。

  当然,这种单一的分层方式也还存在一些不可避免的问题:

  1)KMS通常只能加密一定大小(64KB)的数据,如何处理超过阈值的大规格敏感数据?
  2)经过加密的敏感数据在安全信道上的传输存在隐患和传输成本;同时终端客户也存在对KMS服务可靠和可信性的质疑。

  针对上述问题,Google详述了基于信封加密的密文管理方式。

信封加密

  信封加密是一种多层加密的方式,数据被对应的数据加密密钥(DEK)加密,然后由KEK(Key encryption key)加密DEK,这样在数据的传输过程中,DEK就好像被封存在信封中一样。

  在Google给出的最佳实践中,DEK建议和应用数据存储在相同安全域内的存储中(如集群etcd),不同的应用用户在自己的作用域内有独立的DEK,同时建议在每次加密时分发新的密钥;对于KEK,需要一个集中式的KMS服务对其进行统一管理,包括选择加密方式、访问的权限控制、密钥更新等业务功能。

image.png

  k8s官方1.7版本发布了EncryptionConfig,用户可通过模板配置指定需要加密的资源对象,并通过相应的Providers定义所需的加密方式和密钥。

image.png

​  在1.10版本,k8s发布了KMS plugins相关功能,应用发布者可以通过在EncryptionConfig中定义kms类型的provider指定对接一个外部的kms服务完成上述信封加密式的分层加密方式。

image.png

  以下图的一个secret数据加密落盘过程为例,首先应用用户向apiserver发送了一个向secret中写入数据的请求,apiserver会为每次加密请求生成一个新的DEK,用户数据会被DEK加密,同时KMS provider会通过gRPC协议与指定的KMS plugin通讯;而KMS plugin作为gRPC server端以sidecar的形式部署在集群master节点上,通过它与远端的KMS服务通讯获取用于加密DEK的KEK(key encryption key),完成加密后将加密过的KEK返回给KMS plugin并与加密后的应用数据一起存入etcd中。

  解密时,经过KEK加密的DEK会由plugin发送到远端KMS中获取解密后的DEK返回,再利用该DEK解密存储在etcd中的加密数据。

image.png

  当然,采用信封加密的分层secret管理方式也并不是最优解,远端的KMS server、sidecar方式部署的KMS plugin以及plugin中用于对接KMS服务的认证token等信息都是潜在的攻击点。对于安全等级有更高要求的用户,可以考虑使用对接外部的secret management组件,如HashiCorp Vault,作为当红的secret管理工具,在本次kubecon上也被多位演讲者提及,Vault的一些关键特性如下:

  • Secret存储形式的多样性,任意的kv形式敏感信息(如数据库密码,证书,ssh登录秘钥,openapi身份凭证等);
  • 支持插件式的存储引擎扩展,可对接如etcd,阿里云OSS, Consul,NoSQL,KV,PKI,SSH等多种插件引擎;
  • 支持对接Kubernetes,阿里云RAM,LDAP,TLS,JWT等进行访问认证;
  • 支持加密秘钥的动态生成,续租,撤销和滚动更新;
  • 完备的审计日志;
  • 完备的CLI和RESTful API

image.png

  当前用户可以在阿里云容器服务的应用目录里通过helm方便的部署Vault,我们也会持续关注Vault社区的动向,在后续提供与其对接的KMS plugin方案。

总结

 最后看一下k8s secret管理的特性对比:

image.png

 如何在kubernetes集群中管理secrets的最佳实践总结如下:

  • 根据应用具体的危险模型选取加密方法,比如结合全盘加密和应用层加密
  • 定期轮转加密秘钥
  • 使用信封加密模式,实现秘钥和secret管理的分离
  • 对于kubernetes集群应用的敏感信息防护,推荐使用KMS plugin或对接外部的secrets管理工具。

image.png