4.1.2 Kubernetes组件接口存在的风险
Kubernetes中组件众多,绝大多数组件以基于HTTP或HTTPS的API形式提供服务。其中,我们日常接触比较多的服务及其端口如表4-1所示。
表4-1 Kubernetes服务说明
接下来,我们分别对这些服务进行风险分析。
1.API Server
默认情况下,API Server在8080和6443两个端口上提供服务。
其中,8080端口提供的是没有TLS加密的HTTP服务,且所有到达该端口的请求将绕过所有认证和授权模块(但是仍然会被准入控制模块处理)。保留该端口主要是为了方便测试以及集群初启动。
然而在生产环境开放8080端口,即使绑定本地环回地址(localhost)也是很危险的。如果将该端口暴露在互联网上,那么任何网络可达的攻击者都能够通过该端口直接与API Server交互,继而控制整个集群。
相比之下,6443端口提供的是使用TLS加密的HTTPS服务,到达的请求必须通过认证和授权机制才能够被成功处理。在认证和授权机制配置正确的情况下,6443端口提供的服务安全性会更高。
我们将在4.2节针对8080端口的不安全服务进行实战利用。
2.Dashboard
在按照官方文档所给方式[1]部署完成Dashboard后,默认情况下,我们需要先执行kubectl proxy,然后才能通过本地8001端口访问Dashboard。但是,如果直接将Dashboard端口映射在宿主机节点上,或者在执行kubectl proxy时指定了额外地址参数(如下命令所示),那么所有能够访问到宿主机的用户,包括攻击者,都将能够直接访问Dashboard。
kubectl proxy --address 0.0.0.0 --accept-hosts='^*$'
另外,默认情况下Dashboard需要登录认证,但是,如果用户在Dashboard的启动参数中添加了--enable-skip-login选项,那么攻击者就能够直接点击Dashboard界面的“跳过”按钮,无须登录便可直接进入Dashboard。
我们将在4.2节、6.1节和6.2节对Dashboard未授权访问漏洞被利用的场景进行深入分析。
3.Kubelet
我们知道,API Server是整个Kubernetes的神经中枢,以RESTful API的形式对外提供了大量应用接口。事实上,Kubelet也提供了RESTful API服务,供API Server调用以获取或改变某个Kubernetes节点上的资源状态。然而,这些API的设计意图并非是对外服务,因此官方并没有给出Kubelet的API文档。
默认配置下,Kubelet在10250端口开放上述API服务,另外还监听10248端口,以供其他组件检查Kubelet的运行状态:
root@k8s:~# curl http://localhost:10248/healthz ok
10248端口的服务相对简单,不存在特别的风险,但10250端口却未必。默认情况下,API Server在访问Kubelet的API时需要使用客户端证书,相对来说是比较安全的。但是如果出现以下任一情况:
1)攻击者通过某种方式窃取了API Server访问Kubelet的客户端证书。
2)用户为了方便起见,将Kubelet的--anonymous-auth参数设置为true,且authorization.mode设置为AlwaysAllow。
则网络可达的攻击者都能够直接与Kubelet进行交互,从而实现对其所在节点的控制。虽然官方并未对外公布Kubelet的API文档,但是作为开源项目,Kubelet的源代码是开放的,攻击者完全能够通过阅读源代码找到API的调用格式。
我们将在4.2节对Kubelet未授权访问漏洞进行实战利用。
4.etcd
Kubernetes集群内的各种资源及其状态均存储在etcd中。如果能够有办法读取etcd中的数据,就可能获取高权限,从而控制集群。目前,etcd启动后监听2379和2380两个端口,前者用于客户端连接,后者用于多个etcd实例之间的对端通信。在多节点集群中,为了实现高可用,etcd往往在节点IP上(非本地IP)监听,以实现多节点之间的互通,这可能允许外部攻击者访问etcd。
默认情况下,两个端口提供的服务都需要相应证书才能访问(禁止匿名访问),这为etcd的安全性提供了保障。如果攻击者窃取了证书,或者用户将etcd设置为允许匿名访问,那么攻击者就可能直接访问etcd并窃取数据(利用etcdctl工具):
root@k8s:~# /root/etcd-v3.1.5-linux-amd64/etcdctl --endpoints=https://127.0. 0.1:2379 --cacert ./etcd/ca.crt --cert ./apiserver-etcd-client.crt --key ./ apiserver-etcd-client.key get /registry/serviceaccounts/kube-system/default -o json {"header":{"cluster_id":5269042118365832429,"member_id":2186552333199947133," revision":1699864,"raft_term":2},"kvs":[{"key":"L3JlZ2lzdHJ5L3NlcnZpY2VhY 2NvdW50cy9rdWJ...","create_revision":357,"mod_revision":383,"version":2," value":"azhzAAoUCgJ2MRIOU2VydmljZUFjY291bnQSdQpQCgdkZWZhdWx0EgAaC2t1YmUtc 3lzdGVtIgAqJGRlNjYyY..."}],"count":1}
[1] https://github.com/kubernetes/dashboard#install。