淺談云上攻防—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端口公網暴露
在這個場景中,攻擊者可以利用暴露在公網上的23379端口訪問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組件安全問題。