写点什么

Kubernetes 首个严重安全漏洞发现者,谈发现过程及原理机制

  • 2020-04-22
  • 本文字数:3492 字

    阅读完需:约 11 分钟

Kubernetes首个严重安全漏洞发现者,谈发现过程及原理机制

北美时间 11 月 26 日,Kubernetes 爆出严重安全漏洞,该漏洞由 Rancher Labs 联合创始人及首席架构师 Darren Shepherd 发现。该漏洞 CVE-2018-1002105(又名 Kubernetes 特权升级漏洞,https://github.com/kubernetes/kubernetes/issues/71411)被确认为 严重性 9.8 分(满分 10 分) ,恶意用户可以使用 Kubernetes API 服务器连接到后端服务器以发送任意请求,并通过 API 服务器的 TLS 凭证进行身份验证。这一安全漏洞的严重性更在于它可以远程执行,攻击并不复杂,不需要用户交互或特殊权限。


漏洞被发现并验证后,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、对开源社区的看法。



Rancher Labs 联合创始人及首席架构师 Darren Shepherd,同时也是 Docker 生态核心组织 Docker 治理委员会(DGAB)的全球仅有的四位个人顶级贡献者之一。

Amazon ALB 的问题

这一切都始于 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/http/httputil/#ReverseProxy


相比之下 Websockets 就复杂一点。对于 websocket,你必须查看请求,看到它是一个升级请求,然后发送请求,读取 101 响应,然后劫持 TCP 连接,然后开始来回复制字节。对于反向代理,它不会在此之后查看连接的内容,它只是创建一个“废弃管道”。标准 Go 库中不存在此逻辑,许多开源项目都编写了代码来执行此操作。

错误所在

关于错误所在,太长不看版的解释是,Kubernetes 在启动“废弃管道”之前没有检查 101 响应。在代码的防御中,不检查 101 是挺常见的。(这也是我们上文所说的 Rancher 用户会发现的 Rancher 1.x 和 Rancher 2.x 的问题的原因,即使 Rancher 1.x 和 Rancher 2.x 使用的是完成不同的代码。)错误的场景如下:


  1. 客户端发送 websocket 升级请求

  2. 反向代理向后端服务器发送升级请求

  3. 后端服务器以 404 响应

  4. 反向代理启动复制循环并将 404 写入客户端

  5. 客户端看到 404 响应并将 TCP 连接添加到“空闲连接池”


在这种情况下,如果客户端重新使用 TCP 连接,它将向 TCP 连接写入请求,它将通过反向代理中的“废弃管道”并将其发送到前一个后端。通常这不会很糟糕,例如在负载均衡器的情况下,因为所有请求都会转到同一组同类后端。但是,当反向代理是智能的,并且是由其执行身份验证、授权和路由(即 Kubernetes 所做的全部工作)时,就会出现此问题。

安全漏洞

因为 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/rancher-security-advisory-kubernetes-cve-2018-1002105/12598

感谢开源

我深刻地感到,这次 Kubernetes 的这个安全漏洞的最初发现、修复和最终交付,证明了开源社区强大的生命力。我第一次发现这个问题,也是因为 Rancher 的非付费开源用户给予我们的反馈。事实上, 我们已经确认了这一问题并没有影响 Rancher 2.x 的付费客户,因为 Rancher 的 HA 架构恰好否定了 ALB 的行为 ,但我们还是去研究并解决了这个问题,因为我们太爱我们的开源用户了。也正是在研究和修复这个问题的过程中,我发现了 Kubernetes 自身存在的安全隐患,并通过已建立的安全公开流程向 Kubernetes 社区反馈了该问题。


2020-04-22 18:32627

评论

发布
暂无评论
发现更多内容

自动特征工程在推荐系统中的研究

天枢数智运营

人工智能 推荐系统

听说你还没学Spring就被源码编译劝退了?30+张图带你玩转Spring编译

程序员DMZ

spring Spring源码编译

阿里大型企业级开发必用微服务:深入浅出SpringBoot2.x

小闫

spring jdk 面试 后端 springboot

最详细的Java/后端学习路线

犬来八荒

四面阿里巴巴回来分享面经总结,定级P7架构师

小吴选手

架构 技术 面试 Spring Boot 阿里

分布式柔性事务之最大努力通知事务详解

古月木易

分布式事务

忘掉 Snowflake,感受一下性能高出 587 倍的全局唯一 ID 生成算法

穿甲兵

redis 架构 分布式 CAP Go 语言

业务学习-美团闪购

第519区

太阳马戏团在疫情下的组合式创新

石云升

商业模式 组合式创新 思想实验

五分钟让你搞懂Nginx负载均衡原理及四种负载均衡算法

架构大数据双料架构师

ThreadPoolExecutor 线程池使用

郭儿的跋涉

线程 多线程 线程池

java基础思维导图,让java不再难懂 (建议收藏))

码哥小胖

面试 Spring Boot Java 分布式

数据产品经理的具象化

松子(李博源)

大数据 产品经理 数据产品

2020年7月国产数据库排行:华为、腾讯发新品,中兴、阿里结硕果

墨天轮

数据库 阿里 排行榜

信创舆情一线--印度封禁59款中国App

统小信uos

App 舆情 印度

Kafka 消息丢失与消费精确一次性

奈学教育

kafka

猿灯塔:最详细Dubbo相关面试题

猿灯塔

蟒周刊/427:机器狗已在公开发售,支持用 Python 对其编程...

ZoomQuiet大妈

Python 大妈 蟒营® 蟒周刊 101camp

2.3万个MongoDB数据库遭黑客比特币勒索,你中招了吗?中招怎么办?

墨天轮

比特币 数据库 oracle mongodb 黑客

高效程序员的七个好习惯——你有吗?

小谈

程序员 面试 JVM springboot SpringCloud

原创 | TDD工具集:JUnit、AssertJ和Mockito (二十五)运行测试-在IDE中运行测试

编程道与术

Java intellij-idea 编程 TDD 单元测试

选择排序

wjchenge

第五周作业

武鹏

一致性hash

彭阿三

一致性hash

AndroidStudio真机调试 - Waiting for Debugger

麦洛

Android Studio 真机调试

分布式柔性事务之最大努力通知事务详解

奈学教育

分布式事务

nightingale安装详解

曾祥斌

系统架构师week04 Homework - 互联网架构技术手段和方案

尔东雨田

极客大学架构师训练营

Kafka 消息丢失与消费精确一次性

古月木易

kafka

架构师训练营 - 第五课作业 -20200708- 一致性HASH

👑👑merlan

极客大学架构师训练营 一致性哈希

区块链正处于手脚并用攀爬的“攻坚时刻”

CECBC

数据上链 市场选择

Kubernetes首个严重安全漏洞发现者,谈发现过程及原理机制_文化 & 方法_Rancher_InfoQ精选文章