公司测试环境和预发布环境使用k8s进行容器编排和集群管理已经有一段时间了,期间遇到的问题还挺多的。特在这里进行一下总结。
安全问题
某天,AWS上一个由k8s管理的集群,突然变得不稳定。该集群是用来部署一些测试服务的,现在测试服务基本不能运行。
集群由1个Master和3个Node组成。检查发现基本上每个Node的CPU占用都100%。使用top
命令查看,发现命名为gcc的进程占用了大量CPU。
仔细分析后发现,该进程是一个挖矿程序,指向了一个门罗币矿池,所挖的矿都转到了一个钱包地址。查了这个钱包地址的状态,发现这个地址有大量Hash Rate而且转入转出到额度都挺惊人,看来有很多服务器都被埋下了这个挖矿程序。
杀死该进程,并做了清理工作,服务都恢复了正常。那么问题来了,挖矿程序是怎样植入k8s Node的呢?公司能登录管理这批服务器的人就只有两个,而且相应的安全措施都有。除了这个k8s集群,其他服务器上并没有发现挖坑的程序。问题应该跟k8s有关,查看了这三个Node开放出去的端口,发现10250这个端口被映射到公网。这个端口属于kubelet,kubelet作为node agent运行在每个Node上,负责管理和监控Node上容器的创建。kubelet会运行一个HTTP服务,提供REST API来管理和控制Node。于是检查kubelet日志,发现了有一条比较奇怪的日志,该日志显示用curl下载并执行了一个脚本。而该脚本的用途就是下载挖矿程序和配置文件并启动挖矿。Google了一下,kubelet 10250的发现一篇文章刚好讲的就是这个Analysis of a Kubernetes hack — Backdooring through kubelet。
归根结底这个问题跟k8s配置有关。Kubelet authentication里面有说明。重新配置k8s,并禁止了10250端口开放。
使用k8s,完整阅读和理解官方文档很重要。这不由得让我想起了,k8s API Server的安全问题,API Server默认会开启两个端口: 8080和6443,见官方文档。
直接访问8080端口会返回API列表:
1 | { |
按照官方文档8080端口应该仅用于测试,不能暴露到公网。但实际上也是有人没有注意这一点的。用ZoomEye搜索:metrics healthz +port:"8080"
可以看到有相当多的目标。
使用Kubernetes官方提供的命令行工具可以直接操作相关的node和pod。还可以在容器中执行命令。
查看Pods
进入容器
利用这一点,可以有很多操作的空间,具体我就不再叙述。