Kubernetes首个严重安全漏洞发现者,谈发现过程及原理机制
漏洞被发现并验证后,Kubernetes快速响应并已经发布了修补版本v1.10.11、v1.11.5、v1.12.3和v1.13.0-rc.1。仍在使用Kubernetes v1.0.x至Kubernetes v1.9.x版本的用户,被建议即刻停止并升级到修补版本。
本文由该漏洞的发现者、Rancher Labs联合创始人及首席架构师Darren Shepherd所写。他描述了自己发现这一漏洞的完整经过,剖析了问题的机制与原理,并分享了相应的解决方案以及他本人对Kubernetes、对开源社区的看法。
这一切都始于2016年,当时Rancher Labs刚发布了Rancher 1.6。2016年年中的时候,亚马逊发布了ALB,这是一个新的HTTP(7层)负载均衡器。ALB的设置比ELB容易得多,因此我们会建议用户使用ALB。随后很快,我们开始收到有关ALB后端设置失败的报告,很多随机请求只会得到401、403、404、503的报错。然而,Rancher Labs的团队无法重现这些错误,我们从社区成员那里得到的日志都没有没法成为参考。我们看到了HTTP请求和响应,但无法将其与代码相关联。那个时候,我们只好认为是因为ALB发布不久、产品本身可能存在些错误。除了ALB,我们之前从未遇到任何其他负载均衡器的问题。因此那时,我们只得最终告诉用户不要使用ALB。
时间到了今年8月,又有Rancher社区成员向Rancher 2.1提交了同样的问题( https://github.com/rancher/rancher/issues/14931 )。仍和以前一样,使用ALB会导致奇数401和403错误。这极大地引起了我的关注,因为Rancher 1.x和2.x之间没有共同的代码,而且ALB现在应该也已经相当成熟了。反复深入研究后,我发现问题与不处理非101响应和反向代理缓存TCP连接有关。若您想要真正理解这个问题,您必须了解TCP连接重用、websockets如何使用TCP连接以及HTTP反向代理。
TCP连接重用
在一种非常天真的HTTP方法中,客户端将打开TCP socket,发送HTTP请求,读取HTTP响应,然后关闭TCP socket。很快你就会发现你花了太多时间打开和关闭TCP连接。因此,HTTP协议具有内置的机制,以便客户端可以跨请求重用TCP连接。
WebSockets
Websockets是双向通信,其工作方式与HTTP请求/响应流不同。为了使用websockets,客户端首先会发送HTTP升级请求,服务器会以HTTP 101 Switch Protocols响应来响应这一请求。收到101之后,TCP连接将专用于websocket。在TCP连接的剩余生命周期中,它是被认为是专用于该websocket连接的。这就意味着此TCP连接永远不会被重新使用。
HTTP反向代理
HTTP反向代理(负载均衡器是一种反向代理)从客户端接收请求,然后将它们发送到不同的服务器。对于标准HTTP请求,它只写入请求,读取响应,然后将响应发送到客户端。这种逻辑相当直接,而且Go也包含一个内置的反向代理: https://golang.org/pkg/net/htt ... Proxy 。
相比之下Websockets就复杂一点。对于websocket,你必须查看请求,看到它是一个升级请求,然后发送请求,读取101响应,然后劫持TCP连接,然后开始来回复制字节。对于反向代理,它不会在此之后查看连接的内容,它只是创建一个“废弃管道”。标准Go库中不存在此逻辑,许多开源项目都编写了代码来执行此操作。
错误所在
关于错误所在,太长不看版的解释是,Kubernetes在启动“废弃管道”之前没有检查101响应。在代码的防御中,不检查101是挺常见的。(这也是我们上文所说的Rancher用户会发现的Rancher 1.x和Rancher 2.x的问题的原因,即使Rancher 1.x和Rancher 2.x使用的是完成不同的代码。)错误的场景如下:
- 客户端发送websocket升级请求
- 反向代理向后端服务器发送升级请求
- 后端服务器以404响应
- 反向代理启动复制循环并将404写入客户端
- 客户端看到404响应并将TCP连接添加到“空闲连接池”
安全漏洞
因为101未被处理,所以客户端最终使用TCP连接,该连接是对某些先前访问的后端服务的“废弃管道”。这将导致特权升级。问题是,Kubernetes将仅在反向代理中执行许多请求的授权。这意味着如果我执行一个授权失败的websocket请求路由到一个kubelet,我可以保持与该kubelet的持久连接,然后运行我选择的任何API命令,无论我是否被授权。例如,您可以在任何pod上运行exec并复制出secrets。因此,在这种情况下,已经授权的用户基本上可以获得对kubelet的完全API访问(同样的事情适用于通过kube-aggregation运行的服务)。
当您添加另一个反向代理时,会出现另一个问题。在这种情况下,您将HTTP负载均衡器放在Kubernetes API(非4层负载均衡器)之前。如果执行此操作,那个通过了身份验证的、运行着“废弃管道” 的TCP连接,将会被添加到一个任何用户都可以访问的空闲池中。那么,用户A创建了TCP连接,之后用户B仍可重新使用该连接。这样一来,未经过身份验证的用户就可以访问您的Kubernetes集群了。
此时你可能会感到恐慌,因为当然每个人都会在kube-apiserver前放置一个负载均衡器。唔……首先,您必须运行HTTP负载均衡器,而不是TCP负载均衡器。负载均衡器必须了解HTTP语义才能产生此问题。其次,幸运的是大多数反向代理并不关心101个回复。这就是为什么这个问题其实(在不少开源项目中)存在已久而未被发现的原因。大多数负载均衡器在看到升级请求而非101响应后不会重用TCP连接。所以,如果您会受到这一漏洞的影响,那么您的Kubernetes设置应该已经不可靠了,您应该能看到随机失败或无法完成的请求。至少我知道ALB就是这样工作的,所以你升级到了已修补该漏洞的Kubernetes版本之前,不要使用ALB。
简而言之,Kubernetes的这一安全漏洞会允许具有正确权限的任何经过身份验证的用户获得更多权限。如果您正在运行硬件多租户集群(内含不受信任的用户),您确实应该担心并且及时应对。如果您不担心用户主动互相攻击(大多数多租户集群都是这样),那么不要惊慌,只需升级到已修补该漏洞的Kubernetes版本即可。最坏的情况,如果真的有未经身份验证的用户可以进入您的集群,您的负载均衡器也有可能会阻止这种情况。只要不是将API暴露给世界,并且有在其上放置一些适当的ACL,也许你的集群也还是安全的。
Rancher为Kubernetes保驾护航
对于使用Rancher Kubernetes平台的用户,你们更无须紧张。
对于把集群部署在内网的用户,完全不需要过于担心此问题,因为外部无法直接入侵。
通过Rancher2.0或RKE部署的kubernetes集群的用户同样不用过于担心。因为通过Ranche2.0或RKE部署的集群默认是禁止和匿名用户访问。针对通过pod exec/attach/portforward权限提权问题,目前Kubernetes发布通用的修复方法是通过升级到指定Kubernetes版本来修复,针对此Rancher也已经发布修复程序,具体修复方法请参考: https://forums.rancher.com/t/r ... 12598
感谢开源
我深刻地感到,这次Kubernetes的这个安全漏洞的最初发现、修复和最终交付,证明了开源社区强大的生命力。我第一次发现这个问题,也是因为Rancher的非付费开源用户给予我们的反馈。事实上,我们已经确认了这一问题并没有影响Rancher 2.x的付费客户,因为Rancher的HA架构恰好否定了ALB的行为,但我们还是去研究并解决了这个问题,因为我们太爱我们的开源用户了。也正是在研究和修复这个问题的过程中,我发现了Kubernetes自身存在的安全隐患,并通过已建立的安全公开流程向Kubernetes社区反馈了该问题。
本文转自DockOne-Kubernetes首个严重安全漏洞发现者,谈发现过程及原理机制

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Kubernetes核心概念总结
1、基础架构 1.1 Master Master节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd。 APIServer。APIServer负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。如架构图中所示,kubectl(Kubernetes提供的客户端工具,该工具内部就是对Kubernetes API的调用)是直接和APIServer交互的。 schedule。scheduler的职责很明确,就是负责调度pod到合适的Node上。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定,即将这个pod部署到这个Node上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。 controller manager。如果说APIServer做的是“前台”的工作的话,那controller man...
- 下一篇
Kubernetes DNS服务简介
介绍 域名系统(DNS)是一种用于将各种类型的信息(例如IP地址)与易于记忆的名称相关联的系统。 默认情况下,大多数Kubernetes群集会自动配置内部DNS服务,以便为服务发现提供轻量级机制。 内置的服务发现使应用程序更容易在Kubernetes集群上相互查找和通信,即使在节点之间创建,删除和移动Pod和服务时也是如此。 最近版本的Kubernetes中Kubernetes DNS服务的实现细节已经改变。 在本文中,我们将介绍Kubernetes DNS服务的kube-dns和CoreDNS几个不同的实现版本。 我们一起来看看它们的运作方式以及Kubernetes生成的DNS记录。 如果你想在开始之前就更全面地了解DNS,请阅读“ DNS术语,组件和概念简介 ”。 对于您可能不熟悉的任何Kubernetes主题,可以阅读“ Kubernetes简介 。” Kubernetes DNS服务提供什么? 在Kubernetes版本1.11之前,Kubernetes DNS服务基于kube-dns。 1.11版引入了CoreDNS来解决kube-dns的一些安全性和稳定性问题。 无论处理实...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- MySQL8.0.19开启GTID主从同步CentOS8