浅谈云上攻防——Etcd 风险剖析
Etcd 简介
Etcd 是 CoreOS 团队于 2013 年 6 月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库, 用于服务发现、共享配置以及一致性保障等。目前已广泛应用在 kubernetes、ROOK、CoreDNS、M3 以及 openstack 等领域。
Etcd 内部采用 raft 协议作为一致性算法,基于 Go 语言实现。从组成上来看,Etcd 主要由四个部分组成:HTTP Server、Store、Raft 以及 WAL。我们可以通过 Etcd 架构图来更好的了解 Etcd,Etcd 架构图可见下图所示:
图-1 Etcd 架构图
Etcd 比较常见的版本有 v2 版本和 v3 版本,v2、v3 版本的共同点是共享同一套 raft 协议代码,不同点是二者为两个独立的应用,互不兼容,其接口、存储都是不相同的。
值得注意的是,Kubernetes 集群已经在 Kubernetes v1.11 中弃用 Etcdv2 版本,在新版本的 Kubernetes 中,Kubernetes 采用 Etcd v3 存储数据。
Etcd 与 Kubernetes
在对 Etcd 有了初步了解之后,我们来看一下 Kubernetes 中 Etcd 的应用。
在 Kubernetes 集群中,存在有控制平面组件以及 Node 组件两大类组件,在这两类组件中包含了多种不同功能的组件,这些组件共同保证了 Kubernetes 集群的正常运行。Kubernetes 集群组件结构可参照下图:
图- 2 Kubernetes 集群组件
Etcd 在 Kubernetes 中扮演着控制平面组件的角色,是兼具一致性和高可用性的键值数据库,在 Kubernetes 集群中扮演着保存 Kubernetes 所有集群数据的后台数据库的角色。
Kubernetes 系统中一共有两个服务需要用到 Etcd 进行协同和与存储,分别是 Kubernetes 自身与网络插件 flannel。
在 Kubernetes 集群的配置过程中,需要安装 Etcd 组件,Etcd 的 yaml 文件可见下图:
图- 3 Etcd 组件配置文件
从上文配置文件可见,Etcd 在配置过程中需要配置两个 url 地址:listen-client-urls 以及 listen-peer-urls,分别监听在 2379 端口以及 2380 端口。其中 listen-peer-urls 用于 etcd 集群同步信息并保持连接,而 listen-client-urls 则用于接收用户端发来的 HTTP 请求。
Ectd 常见风险
Etcd 常见风险包括:
启动 etcd 时,未使用 client-cert-auth 参数打开证书校验;
Etcd 2379 端口公网暴露;
由于 SSRF 漏洞导致 Etcd 127.0.0.1:2379 可访问;
Etcd cert 泄露。
我们分别来看一下以上四个风险点分别是如何对 Etcd 造成威胁的。
首先来看一下未使用 client-cert-auth 参数打开证书校验带来的风险:
在启动 etcd 时,正确的做法是使用 client-cert-auth 参数打开证书校验,见下图配置文件红框处:
图- 4 开启证书校验
在打开证书校验选项后,通过本地 127.0.0.1:2379 地址可以免认证访问 Etcd 服务,但通过其他地址访问要携带 cert 进行认证访问
在未使用 client-cert-auth 参数打开证书校验时,任意地址访问 Etcd 服务都不需要进行证书校验,此时 Etcd 服务存在未授权访问风险。
接下来,我们分析一下 Etcd 2379 端口公网暴露所带来的风险:
在配置 Etcd 时,正确的做法是为 listen-client-urls 参数配置一个合理的 IP 地址,Etcd 将监听在给定端口和接口上,如下图红框处:
图- 5 配置 listen-client-urls
由于错误的配置,将 listen-client-urls IP 配置为 0.0.0.0,那么 Etcd 将会在所有接口上监听给定端口,这将导致 Etcd 2379 端口在公网暴露。
接下来,我们分析一下由于 SSRF 漏洞导致 Etcd 127.0.0.1:2379 可访问风险:
即使 Etcd 进行了正确的配置,由于服务器上应用程序的 SSRF 漏洞,导致 Etcd 127.0.0.1:2379 可访,此接口默认不需要证书校验,因此攻击者可以通过 SSRF 漏洞访问此接口并读取 Etcd 中的敏感数据。
最后,我们来看一下 Etcd cert 泄露所带来的风险:
在配置安全通信后, 需要使用 TLS 身份验证来完成 Etcd 服务的访问,通常使用如下的方式有效证书证书进行访问:
如果证书被窃取,攻击者可以使用获取到的证书访问 Etcd 服务。
Ectd 攻击场景
在搭建 Kubernetes 并配置 Etcd 服务时,如果出现了上一章节中提到的错误配置或漏洞风险点,攻击者可以利用 Etcd 的风险点发起攻击。
我们在这里列举集中常见的攻击者攻击方式,通过以攻促防的方式,带领读者了解 Etcd 服务所面临的风险以及威胁。
在开始介绍攻击常见前,我们先来了解一款常见的 etcd 命令行工具——etcdctl。
etcdctl 是一款命令行客户端,提供一些简洁的命令,用户无需使用 HTTP API,可以直接使用 etcdctl 提供的指令与 etcd 服务进行交互。
可以通过如下地址进行下载:
https://github.com/coreos/etcd/releases
接下来我们对几种攻击场景逐一进行分析。
Etcd 初始访问
Etcd 2379 端口公网暴露
在这个场景中,攻击者可以利用暴露在公网上的 2379 端口访问 Etcd 服务。但在这个场景中,攻击者依然面临着两个不同的情况,即当前 Etcd 服务在启动时是否使用 client-cert-auth 参数开启证书校验。
如果当前 Etcd 服务未进行证书校验,则存在未授权访问漏洞,可以通过如下指令获取 top-levelkeys 数据
/etcdctl--endpoints=https://etcd_ip:2379/ get / --prefix --keys-only
具体操作可见下图:
图- 6 获取 top-level keys 数据
如果当前 Etcd 服务使用证书进行校验,则需要使用获取到的证书进行配置并访问
在使用 etcdctl 工具之前,需要配置如下三个环境变量:
ETCDCTL_CERT
ETCDCTL_CACERT
ETCDCTL_KEY
在配置了正确的证书后,即可通过 etcdctl 工具对 Etcd 服务进行访问。
由于 SSRF 漏洞导致 Etcd localhost 端口访问
在这个场景中,由于 SSRF 漏洞导致 Etcd 127.0.0.1:2379 可访问,而且 Etcd 127.0.0.1:2379 地址默认不需要进行证书校验,即可以直接访问,因此当 Etcd 服务器上应用程序存在 SSRF 漏洞时,攻击者可以通过构造内外请求的方式,向 Etcd 服务 API 接口发送恶意指令。
Etcd 凭据窃取
通过初始访问阶段,攻击者获取了 Etcd 服务的访问权限,并可以使用 etcdctl 工具读取 Etcd 中存储的数据,接下来介绍一下在此阶段中应用的技术。
获取 clusterrole key
可以使用如下指令读取存储于 Etcd 中的与 clusterrole 有关的 key
etcdctl--endpoints=https://etcd_ip:2379/ get / --prefix --keys-only | grep/secrets/kube-system/clusterrole。
图- 7 读取 clusterrole 有关的 key
获取 token key 值
可以通过如下指令,通过上一步中获取到的 key,读取其中的值:
etcdctl--endpoints=https://etcd_ip:2379/ get / /xxx/secrets/kube-system/clusterrole-xxx
从返回的数据中,挑选出一个具有高权限的 role 并读取其 token。toke 数据通常以字符串”ey”开头,并截取到字符串
“#kubernetes.io/service-account-token”之前部分,见下图选中部分:
图表- 8 截取 token 数据
至此,我们已经获取了有效的 Kube Apiserver 访问 token。
Kube Apiserver 命令执行
通过上一阶段窃取到的 token 认证访问 Kube Apiserver,使用 kubectl 接管集群。具体操作如下:
kubectl--insecure-skip-tls-verify -s https://kube_apiserver:6443/--token="[ey...]" -n kube-system get nodes
图表- 9 使用 kubectl 接管集群
使用上下文简化 kubectl 操作
生成 context
可以使用如下命令生成 context:
图表- 10 生成 context
配置 context 简化 kubectl 操作
Kubernetes 通过上下文(context),使用简便的名称来对访问参数进行分组。每个上下文都有三个参数:cluster、namespace 和 user。kubectl 工具可以通过 kubeconfig 参数指定我们生成的上下文 context_config:
图表- 11 配置 context
通过这个方式,即可简化 kubectl 操作,无需每次执行 kubectl 命令时填写 TOKEN。
Etcd 防御与加固
通过上文攻击场景介绍,我们提出如下的防护建议用以加固 Etcd 服务:
在启动 Etcd 时,使用 client-cert-auth 参数打开证书校验;
Etcd 数据加密存储,确保 Etcd 数据泄露后无法利用;
正确的配置 listen-client-urls 参数,防止外网暴露;
尽量避免在 Etcd 所在的节点上部署 Web 应用程序,以防通过 Web 应用漏洞攻击 Etcd localhost 地址。
写在最后
Etcd 组件在 Kubernetes 中充当着保存集群数据的后台数据库这一重要角色,因此 Etcd 组件安全对集群来说也是尤为重要。通过上文分析可见,虽然 Etcd 组件提供了较为安全的鉴权功能,以保证数据的安全性,但是由于用户在配置使用 Etcd 组件时安全意识不足或配置错误,将会导致集群数据被非法访问或篡改。Ectd 数据泄露,将会为集群带来严重的安全问题。未来我们将持续关注 Etcd 组件安全问题。
参考链接
https://yeasy.gitbook.io/docker_practice/etcd/etcdctl
https://kubernetes.io/zh/docs/concepts/overview/components/
https://www.huweihuang.com/kubernetes-notes/etcd/etcdctl-v3.html
版权声明: 本文为 InfoQ 作者【腾讯安全云鼎实验室】的原创文章。
原文链接:【http://xie.infoq.cn/article/5e68f49b437ad14c70d11faf7】。未经作者许可,禁止转载。
评论