浅谈云上攻防——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服务的访问,通常使用如下的方式有效证书证书进行访问:

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服务:

在启动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

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

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

(完)