写点什么

浅谈云上攻防——Etcd 风险剖析

  • 2022 年 4 月 29 日
  • 本文字数:3438 字

    阅读完需:约 11 分钟

浅谈云上攻防——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 常见风险包括:

  1. 启动 etcd 时,未使用 client-cert-auth 参数打开证书校验;

  2. Etcd 2379 端口公网暴露;

  3. 由于 SSRF 漏洞导致 Etcd 127.0.0.1:2379 可访问;

  4. 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 服务的访问,通常使用如下的方式有效证书证书进行访问:



ETCDCTL_API=3 etcdctl --endpoints etcd_ip:2379 \  --cert=/etc/kubernetes/pki/etcd/client.crt \  --key=/etc/kubernetes/pki/etcd/client.key \  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
复制代码


如果证书被窃取,攻击者可以使用获取到的证书访问 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 服务:

  1. 在启动 Etcd 时,使用 client-cert-auth 参数打开证书校验;

  2. Etcd 数据加密存储,确保 Etcd 数据泄露后无法利用;

  3. 正确的配置 listen-client-urls 参数,防止外网暴露;

  4. 尽量避免在 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

https://www.cdxy.me/?p=827

https://tttang.com/archive/1465/

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2020.07.20 加入

还未添加个人简介

评论

发布
暂无评论
浅谈云上攻防——Etcd风险剖析_安全攻防_腾讯安全云鼎实验室_InfoQ写作社区