云计算时代操作系统Kubernetes之安全(八)

为了使保存在Kubernetes中的敏感数据能够被加密存储,我们需要介绍Kubernetes平台上一种叫EncryptionConfiguration的对象,在这个对象中,我们可以配置具体需要加密存储的对象信息,比如可以是Secret对象,也可以是任何Kubernetes支持的对象类型。除了这个EncryptionConfiguration对象之外,我们还需要指定秘钥提供者信息,比如笔者在上篇文章介绍的KMS秘钥管理系统,用来提供加密的算法,以及秘钥等信息。

笔者在前边的文章中多次详细的介绍过当我们执行kubectl apply命令背后发生的系统行为,具体来说,kubectl会将用户输入的YAML文件解析后,调用API Server上对应的API将数据发给Master Node,然后Master node进一步对数据进行验证,处理之后,最终会持久化到etcd数据库中,这里大家要注意的是,如果我们要对数据进行加密,这个加密的过程发生在kube-apiserver这个组件上。

如果我们开启加密功能,那么每次我们通过kubectl apply将YAML文件发送到Master Node之后,kube-apiserver组件将加密的任务委托给加密组件,然后将返回的密文保存到etcd数据库中持久化。当敏感信息需要被读取使用的时候,密文会被加密组件的解密模块自动解密,并返回给使用者。

因此用户的角度,这种在kube-apiserver发生的事情对开发和运维人员是透明的,因此开发人员的整个部署和系统管理不受影响。如下图所示:

《1.1 加密组件负责在敏感信息被保存到etcd之前进行加密》

通过上图可以看出,我们创建的Secret对象中包含的敏感数据在被保存到etcd之前会被加密,然后保存到etcd中的数据就是密文了。读者需要特别注意的点是,这个加密的过程其实发生在kube-apiserver这个组件上,虽然上图展示了单独的一层。

有了前边内容的铺垫,接下来我们先创建一个EncrytionConfiguration对象,来让Kubernetes对所有的Secret对象加密,加密使用aescbc算法以及手动配置了秘钥,如下图所示:

《1.2 EC文件来配置Kubernetes对Secret对象加密》

读者可以使用openssl rand -base64 32来生成秘钥,并替换上图中的secret的值。由于加密的过程发生在kube-apiserver上,因此我们必须把这个encryptionconfiguration文件保存到master node上。

在我们的minikube集群上,由于只有一个节点node,minikube既扮演了工作节点,也扮演了master节点,因此我们直接用熟悉的minikube ssh登陆到这台机器上。登陆成功后通过sudo -i切换到root权限。接着在minikube这台虚拟机的目录/var/lib/minikube/certs/下创建文件encryptionconfig.yaml,并把如下的内容贴进去:

《图1.3 在管理节点上创建的EC文件内容》

在管理节点上创建好ec文件之后,接下来我们还需要最后一步,配置kube-apiserver进程来读取EncryptionConfiguration配置文件。由于我们的集群正在运行中,我们必须停止集群,然后启动的时候,使用命令行参数-extra-config来指定我们刚才创建的encryptionconfigration文件,minikube stop本地集群,然后运行如下命令。

minikube start --extra-config=apiserver.encryption-providerconfig=/var/lib/minikube/certs/encryptionconfig.yaml,待集群顺利启动后,我们可以来验证加密功能是否生效。如下图所示:

《图1.4 使用配置文件重新启动minikube集群》

接下来我们从命令行创建一个新的Secret,运行命令:kubectl create secret generic db-secret-encrypted --from-literal=username=qiwangyue --from-literal=password=alicedanghter,secret对象被成功创建后,接下来我们来看看这个叫db-secret-encrypted的Secret对象的数据在etcd中长啥样。

具体如何直接访问etcd的步骤笔者就不重复了,当我们执行./etcdctl get /registry/secrets/default/db-secret-encrypted命令后,返回的数据如下所示:

➜  etcd-v3.4.14-darwin-amd64 ./etcdctl get /registry/secrets/default/db-secret-encrypted

cm􀀀 < 9 􀀀 *􀀀 -􀀀􀀀 ڂ􀀀􀀀􀀀Ȯ􀀀~􀀀6I􀀀􀀀􀀀􀀀=@􀀀􀀀􀀀􀀀e􀀀􀀀􀀀􀀀.􀀀􀀀

8Y

t􀀀􀀀p 􀀀b􀀀

􀀀􀀀V􀀀􀀀􀀀􀀀w􀀀􀀀6􀀀̒􀀀􀀀l􀀀􀀀v􀀀􀀀Ey􀀀q.􀀀^􀀀Z􀀀􀀀n􀀀xh􀀀􀀀$􀀀􀀀􀀀d 놸􀀀1􀀀􀀀y􀀀􀀀Q􀀀􀀀q􀀀􀀀LJј}ߧ􀀀􀀀􀀀􀀀􀀀􀀀􀀀I􀀀w􀀀􀀀%;

如上所示,这样数据在etcd中就以密文的形式被保存了,如果恶意攻击者获取了ETCD的访问权限,从etcd中拿到的数据也无法获知具体的密码等信息,我们的数据就更加安全了。

看到这里,不知道读者是否发现了问题,这样难道真的安全吗?坦白讲,使用encryptionconfigration充其量只能让恶意攻击者获取敏感信息的难度加大,我们并没有彻底保证数据的安全,因为存放在管理节点上的ec文件/var/lib/minikube/certs/encryptionconfig.yaml,如果恶意攻击者获取了管理节点的访问权限,是可以拿到这个key,并基于从etcd获取的数据来解密获取明文,因此笔者才说使用ec充其量只是增加了恶意攻击者获取敏感信息的难度而已。

那我们应该怎么做呢?相信读者已经猜出来了,这就是我们下一篇文章要介绍的,把秘钥和加密后的数据分开到两台服务器上保存,敬请期待笔者的下篇文章!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容