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

通过《四,五,六》三篇文章的介绍,我们实现了一个小目标,老板终于不用担心保存在配置仓库和开发人员机器上的YAML文件中敏感数据的安全了。但是安全是一个体系性的概念,墨菲定律无时无刻都在提醒着我们,只要数据以明文形式存储着,就可能会被恶意攻击者截获,凡事有可能出错,就一定个会出错。

我们知道敏感信息被部署到Kubernetes中之后,数据会以base64编码的方式保存到ETCD持久化数据库中,而base64由于并不是加密,因此数据基本还是以明文的形式存在。所以今天这篇文章,我们就来首先验证一下,保存在etcd中的数据是否如笔者所说以base64编码的形式被存储?确定风险真实存在后,接下来我们来看看具体如何加密保存在Kukbernetes中的敏感数据。如下图所示:

《图1.1 对保存在Kubernetes中的敏感数据加密》

当然,上边的加密只是第一步,我们的最终目的是在Kubernetes中集成如阿里巴巴秘钥管理服务这样的外部秘钥管理工具,来彻底以安全的方式管理和使用秘钥,如下图所示:

《图1.2 通过KMS来管理秘钥》

我们日常开发的系统,基本上都需要数据库的支持,而访问数据库需要用户名和密码,因为数据库中保存着大量企业的敏感信息,比如说订单,客户,合同等,因此访问数据库的用户名和密码需要保证机密性,即便是系统被攻破,用户名和密码也应该能保持机密而不被窃取。

但是部署在Kubernetes平台上的应用,即便是我们通过Helm Secrets这样的插件对这些数据进行了加密,但是资源被apply到集群上之后,这些配置信息在etcd中是以base64编码的形式被保存,因此根本谈不上机密,因为可以访问etcd的用户,都可以访问到这个数据,安全性非常堪忧啊。

在数据安全领域,有两个概念需要给大家科普一下:data in transit和data at rest。data in transit说的是如何确保线路上的数据安全,比如我们要把数据从A点发送到B点,中间要经历多个路由器,那么data in transit具体要解决的就是在传输的过程中,如何确保数据不被恶意攻击者截获并获取隐私信息。一般情况下我们通过mTLS来确保线路上的数据安全。

data at rest主要解决的数据被保存在磁盘,数据库中的场景下,如何保证安全机密性,这是我们接下来要讨论的重点。关于data in transit和data at rest这两个概念的示意图如下:

《图1.3 数据安全以及两种状态》

了解了数据的两种安全状态,在介绍具体的Kubernetes数据加密方案之前,我们先在etcd中创建一个隐私数据,然后从攻击者的角度直接访问etcd来获取这个数据,以此来强调我们后续介绍内容的必要性和重要性。

首先在集群上创建一个包含用户名和密码的资源:kubectl create secret generic db-secret --from-literal=username=julia --from-literal=password=yunpandaughter,我们可以通过运行kubectl get secrets来验证资源被成功的创建。

接着我们需要在自己的机器上安装etcdctl客户端工具,具体的安装和操作系统的版本有关系,读者可以参考官方网站:https://github.com/etcd-io/etcd/releases 来进行安装。

有了etcdctl这个命令行工具后,接下来我们就可以通过这个工具来连接到本地的etcd数据库了。对于Kubernetes平台来说,etcd服务器运行在kube-system这个命名空间中,提供了外部可访问的2379端口。由于这是一个内部的端口,因此我们需要使用kubectl port-forward来在本地创建一个代理服务。首先在自己的机器上运行kubectl get pods -n kube-system,从输出的结果中确认etcd运行的pod名称,以下是笔者minikube环境的输出:

➜  hello-demo kubectl get pods -n kube-system

NAME                                        READY  STATUS    RESTARTS  AGE

coredns-f9fd979d6-qpn9f                      1/1    Running  40        247d

etcd-minikube                                1/1    Running  73        294d

接着运行kubectl port-forward -n kube-system etcd-minikube 2379:2379 在本地创建访问etcd的代理。为了访问etcd中保存的键值对数据,我们还需要放访问etcd需要的证书从运行的pod中拷贝出来。在笔者的机器上,首先minikube ssh到虚拟机上,然后在另外一个命令行通过命令:minikube mount /Users/gaopanqi/etcd-download-test:/tmp 将本地的文件夹挂载到minikube的虚拟机文件系统的/tmp目录,然后我们就可以在minikube虚拟中,从目录/var/lib/minikube/certs/etcd下把peer.key和peer.crt文件拷贝到挂载的目录/tmp,拷贝完成后就可以退出了。

注:从Kubernetes的容器实例中拷贝文件可以使用笔者之前介绍的kubectl cp工具,但是由于ectd-minikube这个容器镜像中并不包含tar工具包,因此如果你视图用kubectl cp来拷贝证书到本地,会返回126错误码,这个错误码的意思就是系统不存在这个命令,读者可以按minikube mount一个本地文件夹到minikube虚拟机,然后minikube ssh,然后把key文件从对应的目录拷贝到挂载目录,这样数据机会出现在本地。

有了证书文件,我们就可以访问etcd中保存的信息了,在自己的机器上执行export ETCDCTL_API=3 ETCDCTL_INSECURE_SKIP_TLS_VERIFY=true ETCDCTL_CERT=/Users/gaopanqi/etcd-download-test/peer.crt ETCDCTL_KEY=/Users/gaopanqi/etcd-download-test/peer.key,然后在相同的命令行窗口执行:./etcdctl get /registry/secrets/default/db-secret,在笔者的机器上返回的结果如下:

《图1.4 通过etcdctl可以获取到任意的敏感信息》

虽然说我们从etcd返回的数据不太好看,但是不难从中找到敏感数据,如上图中高亮部分显示(可以对比我们从命令行创建时候传入的参数,这种系统攻击者几乎没有任何抵抗力)。希望读者通过上边的这些内容,可以体会到etcd服务器中的数据是如此容易就被泄漏,因为大部分黑客掌握的攻破系统的技术和方法远远大于笔者,因此我们读者如果已经在Kubernetes上部署自己的应用了,赶紧开始评估是不是有敏感数据。如果有,也不用惊慌,我们下一篇文章来重点介绍如何对保存在Kubernetes的etcd数据库中的数据加密存储,敬请期待!

你可能感兴趣的:(云计算时代操作系统Kubernetes之安全(七))