Kubernetes安全

背景

​ 随着微服务的快速发展,容器化的概念愈发的火热。裸用Docker暴露出大量的痛点。为了解决容器的编排管理,一些大型互联网公司已经转向Kubernetes。当然Kubernetes给我们带来巨大红利的同时,也引入了大量的安全风险。错误使用可能导致整个集群的沦陷。所以笔者花时间对k8s这块的风险进行研究和学习,目前只对一些漏洞进行分享,企业会因为复杂的人员和环境产生更多的安全问题,后续再聊。

为什么要用k8s

真正的生产型应用会涉及多个容器。这些容器必须跨多个服务器主机进行部署。Kubernetes 可以提供所需的编排和管理功能,以便您针对这些工作负载大规模部署容器。借助 Kubernetes 编排功能,您可以构建跨多个容器的应用服务、跨集群调度、扩展这些容器,并长期持续管理这些容器的健康状况。

K8S的作用:

  • 跨多台主机进行容器编排。
  • 更加充分地利用硬件,最大程度获取运行企业应用所需的资源。
  • 有效管控应用部署和更新,并实现自动化操作。
  • 挂载和增加存储,用于运行有状态的应用。
  • 快速、按需扩展容器化应用及其资源。
  • 对服务进行声明式管理,保证所部署的应用始终按照部署的方式运行。
  • 利用自动布局、自动重启、自动复制以及自动扩展功能,对应用实施状况检查和自我修复。

核心组件图

核心组件图

安全风险

kube-apiserver 的未授权访问

提供HTTP/HTTPS RESTful API,是Cluster前端接口,各种客户端工具以及Kubernetes其他组件可以通过它管理Cluster的各种资源。

常见的默认端口: 8080 (http)、 6443(https)

直接访问:会返回可用的API列表

如果Kubernetes API Server配置了Dashboard,通过路径/ui即可访问

未授权的情况下:可通过kubectl或者第三方客户端生成HTTP请求,发送给API Server。或者是集群内部的服务dashborad通过API Server对集群进行控制操作

etcd未授权

通常etcd数据库会被安装到master节点上,rest api可获取集群内token、证书、账户密码等敏感信息,默认端口为2379。访问路径/v2/keys/?recursive=true,以JSON格式返回存储在服务器上的所有密钥

未授权返回信息: {“action”:”get”,”node”:{“dir”:true}}

进一步利用可下载: https://github.com/etcd-io/etcd/releases etcdctl

如: etcdctl –endpoints=xxx.xxx.xxx.xxx:2379 member list

Kublet API未授权

通过未授权访问Kublet API, curl -sk https://k8-node:10250/runningpods/ 获取到pod信息

然后 curl -sk -XPOST “https://k8-node:10250/run///“ -d “cmd=id” 执行系统命令

一般不能利用会直接返回: Unauthorized

可直接控制所有的pod

如果通过runningpods API可获取相关node节点的信息的话,可直接拼接下面三个参数控制相关服务器

Docker Engine 未授权访问Rest API

当docker配置了Rest api,我们可以通过路径xxx.xxx.xxx.xxx/containers/json 获取服务器主机当前运行的container列表。找到存在未授权访问的目标主机

通过远程访问接口,获得容器访问权限。

docker -H tcp://xxx.xxx.xxx.xxx:2375 run -it -v /root/.ssh/:/mnt alpine /bin/sh

token泄露

Service Account 概念的引入是基于这样的使用场景:运行在 Pod 里的进程需要调用 Kubernetes API 以及非 Kubernetes API 的其它服务(如 image repository/被 mount 到 Pod 上的 NFS volumes 中的 file 等)。

Kubernetes 默认会挂载 /run/secrets/kubernetes.io/serviceaccount/token 到各个 Pod 里,但这样会导致攻击者进入容器后读取 token 就能和 Kubernetes API 通信了。

10255/pods

查看所有pod节点信息

Kubernetes相关高危端口:

端口 标识 描述
4149 kubelet 用于查询容器监控指标的cAdvisor端口
10250 kubelet 访问节点的API端口
10255 kubelet 未认证的只读端口,允许访问节点状态
10256 kube-proxy kube-proxy的健康检查服务端口
9099 calico-felix calico的健康检查服务端口(如果使用calico/canal)
6443/8080 kube-apiserver kube-apiserver 接口
2379 etcd etcd数据库
2375 Docker Engine 容器远程访问接口

最佳安全实践:

https://github.com/freach/kubernetes-security-best-practice

扫描脚本:

https://github.com/aquasecurity/kube-hunter

参考

https://www.cnblogs.com/itoak/p/12925565.html

文章作者: Screw
文章链接: http://screwsec.com/2020/05/30/Kubernetes%E5%AE%89%E5%85%A8/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Screw's blog