写给 Kubernetes 工程师的 mTLS 指南

471930ef80c18b9f99551df96cdfeea7.png

f77ec8cc44fd43daae427948bf58cf95.gif

本文翻译节选自 A Kubernetes engineer’s guide to mTLS[1],为了便于读者理解,笔者对原文做了一点修改 (本文删除了原文中的与主题关系不大的 Linkerd 安装的部分,将 Twillio 替换成国内读者比较熟悉的 GitHub)。因为笔者最近在研究 Istio 中的身份认证及 SPIFFE,对如何在 Kubernetes 中应用 mTLS 以及为什么要使用 mTLS 产生了浓厚的兴趣,再回想起五年前手动安装 Kubernetes 时,因为给集群开启 TLS 问题而导致安装停滞不前。

本文的主要观点是:在 Kubernetes 中我们不能仅依靠网络层加密,还需要 mTLS 来对客户端和服务端进行双向的传输层认证。本文将聚焦于 TLS 的真实性,以及证书管理的难题,说明服务网格对于在 Kubernetes 中开启 mTLS 带来的便利。


简介

Mutual TLS(双向 TLS),或称 mTLS,是 Kubernetes 中的一个热门话题,尤其是对于那些负责为应用程序提供传输层加密的人来说。但是,你有没有考虑过,什么是 mTLS,它提供什么样的安全,为什么需要 mTLS?

本指南我将介绍什么是 mTLS,它与常规 TLS 的关系,以及为什么它与 Kubernetes 有关。我还会谈论 mTLS 的一些优缺点及替代方案。

什么是 mTLS?

对于常规 TLS,只需要服务端认证,mTLS 相对来说有一个额外的规定:客户端也要经过认证。但这意味着什么,为什么要这样做呢?

在回答这些问题之前,我们需要先对 TLS 有一个基本的了解。TLS 是一个传输层协议,旨在为 TCP 连接提供安全保障(我们将在下面看到安全的确切含义)。TLS 在传输层工作,可以与任何使用 TCP 的应用层协议结合使用。例如,HTTPS 是 HTTP 与 TLS 的结合(HTTPS 中的 S 指的是 SSL,即 TLS 的前身),HTTP 不需要做任何改变来适应 TLS(至少,在协议层面。在实践中,随着 HTTPS 的引入,HTTP 的使用方式肯定已经发生了变化。例如,像 HSTS 这样的功能现在被用来防止 HTTPS 可能发生的某些类型的攻击)。

因为 TLS 中存在各种各样的问题,使得其从安全的角度来看是不理想的。TLS 规范复杂,而且没有得到充分的说明,有些地方并没有真正的意义,而且不管怎样,实现起来也不会 100% 符合 TLS 规范。

尽管有这些担忧,TLS 还是无处不在。你现在就在使用 TLS:这个页面是通过 HTTPS 提供的,你可能在浏览器的 URL 栏中看到一个小锁图标。

TLS 提供什么样的安全性?

大多数人把 TLS 与加密联系起来。但 TLS 不仅仅是这样。TLS 为连接提供了三种安全保证:

  • • 真实性:任何一方都能证明他们是自己所声称的身份。

  • • 保密性:其他人无法看到正在交换的数据。

  • • 完整性:收到的数据与发送的数据相同。

因此,虽然 TLS 确实给你提供了加密 —— 这就是它实现保密的方式 —— 但从 TLS 的角度来看,这对安全通信来说是不够的:你需要所有这三种属性。如果你没有真实性,那么有人就可以在连接的另一端进行欺骗。如果你没有完整性,那么有人可以修改通信中的关键信息。如果你没有保密性,那么任何人都可以监听。

在这三种保证中,本文主要关注真实性。

mTLS 什么时候有用?

回到我们最初的定义:mTLS 是简单的常规 TLS,其中有一个额外的规定,即客户端也要经过认证。有了对 TLS 的基本了解,我们现在可以解析这个声明了。TLS 保证了真实性,但默认情况下,这只发生在一个方向上:客户端对服务器进行认证,但服务器并不对客户端进行认证。

为什么 TLS 的默认只在一个方向进行认证?因为客户端的身份往往是不相关的。例如,在加载这个页面时,你的浏览器已经验证了要访问的网站服务端的身份,但服务端并没有验证你的浏览器的身份。它实际上并不关心你的浏览器的身份。

当然,不验证客户端身份对于提供网页服务是有意义的,但有很多类型的通信,客户端的身份也很重要。例如 API 调用:如果你调用像 GitHub 这样的服务,那么 GitHub 需要知道你是谁 —— 除其他原因外,这样他们就可以给你发送账单。如果不向 GitHub 提供某种客户端身份,你就不能对 GitHub 的 API 进行调用。

但 GitHub 并不使用 mTLS。相反,你通过给 GitHub 一个秘密的认证令牌(token)来认证自己,这个令牌是创建账户时分配给你的。坦率地说,mTLS 设置起来很烦人(后面会有很多这方面的内容),所以如果你提供像 GitHub 这样的公共 API,你可能会只使用 auth token。

然而,使用 mTLS 的认证有一些非常强大的 auth token 方法没有的优势。首先,mTLS 认证可以完全在应用程序之外完成,不需要任何应用程序级别的功能来创建、注册或管理身份。使用 auth token 时,在你进行第一次 GitHub API 调用之前,你需要登录网站,创建一个账户,获得令牌(尽管这个客户端令牌流程没有使用 TLS 客户端认证,但它仍然依靠 TLS 服务器认证来保证安全。TLS 确保令牌来自 GitHub 而不是一个伪装者)。GitHub 的 API 必须知道这个 auth token,并提供将其传递给 API 调用和管理它的方法。但有了 mTLS,一个全新的客户端就可以直接认证自己,即使从没有人见过它。而应用程序不需要知道任何关于认证的事情,也不需要提供端点来管理认证。

综上所述,我们看到 mTLS 非常适合以下情况:

  1. 1. 你需要安全通信;

  2. 2. 你关心客户端的身份;

  3. 3. 不想为管理身份建立应用级流程;

  4. 4. 你可以管理实际实施的复杂性。

有种场景具有所有这些特征,那就是微服务!

使用 mTLS 来保护微服务的安全

mTLS 是保证微服务之间跨服务通信安全的好方法,原因就在上面。

首先,你想要安全的通信。当我们把我们的应用程序拆分为多个服务时,我们最终会在这些服务之间的网络上发送敏感数据。任何能够进入网络的人都有可能读取这些敏感数据并伪造请求。

第二,你关心客户端的身份。首先,你要确保你能知道调用是什么时候发生的,以便进行诊断,并正确记录指标等事项。此外,你可能想对这些身份进行授权(允许 A 调用 B 吗)。我们将在后面讨论更多关于授权的问题。

第三,你并不真的想为管理服务身份建立应用级的流程。这不是业务逻辑,开发人员的时间最好用在其他地方。

最后,如果你控制了平台,你实际上可以管理实施 mTLS 的复杂性。或者至少,比 GitHub 做得更好。在我们的 GitHub 例子中,每个用户都必须解决对 GitHub 进行身份验证的难题。这个挑战越难,对用户就越不利(对 GitHub 的底线也越不利)。但是,如果我们能在平台层面上实现 mTLS,我们就能一次性支付成本,而不是为每个服务或每个用户支付。

综上所述,mTLS 非常适用于确保微服务之间的通信安全。但是有一个问题。

实施 TLS 的难点:证书管理

到目前为止,我们已经为 mTLS 描绘了一幅美好的图景。客户端和服务器愉快地相互认证,然后它们之间的通信就安全了。在实践中,阻碍 mTLS 工作的最大挑战是证书管理

TLS 中的认证是通过 公钥密码学公钥基础设施(PKI)进行的 。这两者本身就是一个巨大的话题,在这篇文章中我们不会去讨论这些细节。但简而言之,它们涉及大量的证书。

TLS 认证基于 X.509 证书。X.509 证书中包含身份公钥。公钥有一个相应的私钥,它不是证书的一部分。TLS 认证分两步,第一步是向对方展示你的证书,然后用私钥来证明证书中包含的身份属于你(公钥密码学的神奇之处在于,任何复制证书的人都无法进行这种证明,因为他们没有私钥。因此,你可以非常自由地使用证书,包括通过明文渠道发送证书或将其存储在公开场合)。

X.509 证书是由一个 证书授权机构(Certificate Authority,简称 CA) 签署,其中包括受 CA 信任该的身份。证书用于 TLS 认证的第二步:如果有人向你展示他们的身份并证明他们拥有该身份,你现在必须决定是否信任该身份。TLS 在这里使用了一个简单的规则:如果证书是由 CA 签署的,且你信任该 CA,那么你就应该信任该身份。如何验证 CA 对证书的签名?通过使用该 CA 本身的 X.509 证书。怎么知道是否应该信任该 CA?嗯,这个就与 TLS 协议本身无关,你会被外界告知应该信任它(例如,你的浏览器带有知名公共 CA 的证书,如 Verisign、Digicert 等,这些证书在发布时被打包在一起。当你下载 Firefox 时,你相信 Mozilla 已经把正确的证书放进了浏览器。对于集群内的通信,我们将创建我们自己的 CA,这意味着我们也必须以一种安全的方式,将这个 CA 的证书分发给集群的每个部分,这些部分需要做出信任决定)。

CA 也签发证书。要获得证书,你首先要创建公钥和私钥对。你保留私钥,嗯,私钥 —— 千万不要在网络上发送私钥 —— 你向 CA 发送一个包含公钥和你身份的证书签名请求(Certificate Signing Request,简称 CSR)。如果 CA 批准了这个请求,它就会创建和签署证书,并把证书发送给你。

所以,证书管理就是就成了证书创建和分发流程中的挑战。我们需要确保有一个 CA,每个服务都可以向其发送 CSR,而且 CA 可以把证书发送给服务。我们还需要确保 CA 的安全,没有人能够访问任何服务的私钥,而且每个服务都知道自己的身份,而且不能被改变。

在 Kubernetes 这样的环境中,服务实际上是一组不断变化的副本,可以随时创建或销毁,每个副本都需要自己的证书,这使得证书分发的挑战更加严峻。

而且 , 由于在实践中,减少证书暴露损失(即当有人未经授权获得秘钥时)的最好方法是证书轮换:缩短证书的寿命,在证书过期前重新颁发。这意味着我们需要每隔 n 小时为每个副本重复整个证书请求和签名的流程。

如果我们想在多个集群之间扩展安全通信,需要一种方法来确保在一个集群中产生的身份可以被其他集群所使用,而且如果某个集群被破坏,我们可以禁用该集群而不禁用其他集群,这就进一步增加了证书管理的复杂性,因为这将产生更多的证书。

总之,实施 mTLS 涉及到管理大量的证书,消耗大量的时间。这一挑战的复杂性令人生畏。但尽管如此,mTLS 在 Kubernetes 的世界里已经看到了一些复兴的趋势。这是因为有一门技术使 mTLS 变得可行:服务网格。

Kubernetes、mTLS 和服务网格

服务网格是为集群开启 mTLS 的一个绝佳的机制。它不仅可以处理证书管理的挑战,还可以处理建立和接收 TLS 连接本身。它使得为集群添加 mTLS 成为一个零配置的操作:当你在 Kubernetes 集群上安装服务网格的时候,网格化的 pod 之间的所有通信都自动被 mTLS 化。对于像 mTLS 这样复杂的东西来说,这是很不可思议的。

这一切之所以能够实现,是因为 Kubernetes 使一些本来非常复杂的事情,如 sidecar 模式,变得简单易行。得益于 Kubernetes,服务网格可以:

  • • 透明地将一个 sidecar 代理注入到每个应用程序的 pod 中,并通过该代理路由所有进出 pod 的 TCP 通信。

  • • 将一个内部 CA 作为其控制平面的一部分,签发 TLS 证书,并将该 CA 的证书安全地分配给所有代理。

  • • 使用这个 CA 向每个代理发放短期的证书,与 pod 的 Kubernetes ServiceAccount 身份相联系。

  • • 每隔 N 小时重新签发这些证书。

  • • 让每个代理对所有使用这些证书的 pod 的连接执行 mTLS,确保客户端和服务器双方都有有效的身份。

  • • 在连接进入应用程序之前,使用这些身份应用授权策略。

当然,这只是一种简化的描述。例如,Linkerd 实际上使用了两级 CA,一个在集群层面,一个在全局层面,以便允许跨集群通信。Linkerd 可以使用多个信任根,所以你也可以轮流使用 CA。

常见问题:mTLS 实际上能保护什么?

事实上,mTLS 只能用于防止特定的攻击:未经授权的网络访问。阻止入侵者嗅探网络请求中的内容,阻止冒充服务进行访问。

但是有很多东西是 mTLS 不能保护的,例如未经授权主机访问。如果黑客入侵进了主机,mTLS 保护就无济于事了:入侵者可以读取密匙,嗅探或欺骗连接,颠覆 CA 并造成破坏,或任何其他恶意活动。

确保 Kubernetes 的安全并不容易,实际上 mTLS 只解决了 Kubernetes 的一小部分安全漏洞。

mTLS 与 IPSec 或 Wireguard 等网络层加密相比怎么样?

在 Kubernetes 中,一些 CNI 插件如 Calico 和 Cilium 可以通过 IPSec 或 Wireguard 等协议提供网络层加密。像服务网格一样,这种网络层加密可以提供传输层加密,而应用程序本身不需要做任何事情。

虽然网络层加密可以与 mTLS 结合使用,作为一种深度防御的形式,但有几个原因可以说明网络层加密不足以替代 mTLS。

如你所料,网络层加密的最大缺点是围绕身份的。因为它们在网络层工作,Wireguard 和 IPSec 只能提供网络身份,而不是工作负载身份。换句话说,它们不是使用工作负载本身固有的身份(比如 SPIFFE[2] 或者 Kubernetes 的 ServiceAccount),而是使用该工作负载运行的 IP 地址。

依靠网络身份有一系列的问题,包括:

  1. 1. 身份终止在集群边界。Kubernetes 中的 IP 地址是以集群为范围的,当跨越集群边界的时候,你就必须想出另一种身份机制。因此,如果你正在进行跨集群通信,或者想要一个涵盖非 Kubernetes 工作负载的身份系统,IP 地址就会落空。

  2. 2. 没有直接的机制进行细粒度的授权。网络层方法不能访问七层信息,如 HTTP 路由、动词以及 gRPC 方法(有些复杂的 CNI 通过启动一个七层代理来解析数据,以服务网格模式来解决这个问题)。

  3. 3. 这不是零信任。零信任的安全模式要求我们将安全边界转移到尽可能细的层次。在 Kubernetes 中,这个单位就是 pod。有了服务网格的 mTLS,你的安全边界就在 pod 层面,但对于网络层的加密,你的安全边界最多只能在主机层面执行;你必须信任网络,等等。

由于这些原因,在 Kubernetes 中 mTLS 为你提供了比仅仅依靠网络层加密更好的安全态势。

引用链接

[1] A Kubernetes engineer’s guide to mTLS: https://buoyant.io/mtls-guide/
[2] SPIFFE: https://spiffe.io/

更多云原生社区资讯,加入云原生社区讨论群,欢迎加入云原生社区,点击阅读原文了解更多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二、solidity 基础进阶(2.1)—— library 库合约《实战NFT web3 solidity(新版本0.8.+)》

《web3 solidity0.8.版本(持续更新新版本内容) 基础到实战NFT开发》会及时更新新版本 solidity 内容,以及完成最终的 NFT 实战商业项目部分。 注:由于是付费专栏内容,若有错误请及时联系1_bit,博客链接&am…

paper 17 : 机器学习算法思想简单梳理

前言: 本文总结的常见机器学习算法(主要是一些常规分类器)大概流程和主要思想。 朴素贝叶斯: 有以下几个地方需要注意: 1. 如果给出的特征向量长度可能不同,这是需要归一化为通长度的向量(这里以…

BZOJ1179 Atm //缩点+spfa

1179: [Apio2009]Atm Description Input 第一行包含两个整数N、M。N表示路口的个数,M表示道路条数。接下来M行,每行两个整数,这两个整数都在1到N之间,第i1行的两个整数表示第i条道路的起点和终点的路口编号。接下来N行&#xff0c…

基于Spring Boot和Spring Cloud实现微服务架构学习

目录 Spring 顶级框架 Spring cloud子项目 WHAT - 什么是微服务 微服务简介 微服务的具体特征 SOA vs Microservice HOW - 怎么具体实践微服务 客户端如何访问这些服务? 服务之间如何通信? 这么多服务,怎么找? 这么多服务&#x…

ArcGIS实验教程——实验三十七:基于ArcGIS的太阳辐射分析案例教程

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据)》 文章目录 一、太阳辐射的基本概念1. 视域2. 太阳图3. 星空图二、太阳辐射ArcGIS案例实现1. 对该区域进行太阳辐射区域分析2. 对单个点的太阳辐射进行分析太阳辐射是地球上各种物理过程和生物过程的…

ArcGIS实验教程——实验三十八:基于ArcGIS的等高线、山体阴影、山顶点提取案例教程

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据)》 文章目录 1. 加载DEM2. 提取等高距为15m的等高线3. 提取等高距为75m的等高线4. 生成山体阴影5. 生成三维等高线6. 提取山顶点7. 实验数据下载地址山顶点指那些在特定邻域分析范围内,该点都比周围…

(2.3)其他补充—— 二、solidity 基础进阶《实战NFT web3 solidity(新版本0.8.+)》

《web3 solidity0.8.版本(持续更新新版本内容) 基础到实战NFT开发》会及时更新新版本 solidity 内容,以及完成最终的 NFT 实战商业项目部分。 注:由于是付费专栏内容,若有错误请及时联系1_bit,博客链接&am…

如何在web api中使用SignalR

说明: 在webapi中使用signalr,使用IIS 环境: vs2012, .net4.5 第一步:建web api项目 第二步:nuget导入signalr Install-Package Microsoft.AspNet.SignalR Install-Package Microsoft.Owin.Cors (用于…

Directx11学习笔记【二】 将HelloWin封装成类

我们把上一个教程的代码封装到一个类中来方便以后的使用。 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 MyWindow.h文件 1 /***************************************************…

Badboy自动化测试工具11 导出脚本用于Jmeter并发测试

本节主要讲解利用Jmeter进行并发测试和引入图像报表 1. 在Jmeter中打开上节课(10)Badboy导出的在拉手网查询KTV的脚本Lashou_Search.jmx. 2. 右击Lashou节点,Add->Listener->Aggregate Graph & Graph Results 3. 对图像报表进行配置…

ArcGIS实验教程——实验三十九:ArcGIS多元分类(ISO聚类分析、最大似然分类、主成分分析)案例教程

ArcGIS实验视频教程合集:《ArcGIS实验教程从入门到精通》(附配套实验数据)》 文章目录 一、ISO聚类1. ISO聚类简介2. ISO聚类进行非监督分类实验操作二、最大似然分类1. 最大似然简介2. 最大似然分类实验案例三、主成分分析1. 主成分分析简介2. 主成分分析实验案例四、配套实…

ABP Framework 5.3.0 版本新增功能和变更说明

ABP Framework 5.3.0 稳定版已在2022年6月14日正式发布。以下是本版本的新增功能:• “开始”页面提供创建单层项目选项• 启动模板提供 PWA 支持• Volo.Abp.Gdpr.Abstractions 包介绍• 将发件箱中的事件批量发布到事件总线• eShopOnAbp 项目改进和电子书公告• …

智能合约开发——TypeScript 基础(全)

TS 准备 首先我们准备一个目录,使用 dos 进入到某目录,当然你直接 vs 打开终端执行也是没有问题的: 执行以下命令安装 typescrip(不用进入目录,直接安装即可): npm install -g typescript我是…

利用Signalr实现手机端App扫码登录web页面

实现原理: 1、web登录页面,利用jquery.qrcode展示一个随机生成的登录码的二维码; 2、手机App扫描二维码取得登录码; 3、手机App将本地用户id登录码通过api提交服务器; 4、服务器api,收到手机App请求&am…

【ArcGIS风暴】ArcGIS栅格影像(NDVI)归一化处理的两种方法精解

【ArcGIS遇上Python】ArcGIS批量处理栅格影像(NDVI)归一化完整案例代码 图像归一化是指对图像进行了一系列标准的处理变换,使之变换为一固定标准形式的过程,该标准图像称作归一化图像。 原始图像在经历一些处理或攻击后可以得到多种副本图像,这些图像在经过相同参数的图像…

以小见大:一个领域建模的简单示例,理解“领域驱动”。

背景:航空公司为了确保飞行路线不发生冲突,需要开发一款飞行路线管理软件。过程:我们先去找这个领域的专家,自然是作为平时管理和维护机场飞行秩序的工作人员;我们第一个目标就是与他们沟通,也许我们并不能…

【ArcGIS遇上Python】ArcGIS批量处理栅格影像(NDVI)归一化完整案例代码

文章《ArcGIS栅格影像(NDVI)归一化处理的两种方法精解》详细介绍了ArcGIS中进行NDVI影像归一化处理的两种方法,但是无法批量进行,本文就放大招用Python实现批量NDVI归一化处理,大大提高了工作效率,还不赶快Get了? 完整Python代码: import arcpy from arcpy import env…

Spark1.0.0 属性配置

1:Spark1.0.0属性配置方式Spark属性提供了大部分应用程序的控制项,而且能够单独为每一个应用程序进行配置。在Spark1.0.0提供了3种方式的属性配置:SparkConf方式 SparkConf方式能够直接将属性值传递到SparkContext;SparkConf能够对…

Lync Server 2010迁移至Lync Server 2013部署系列 Part1: 扩展AD架构

由于最近直在忙Lync 升级,好久没有更新博客了,今天开始将对最近做的Lync Server 2010迁移至Lync Server 2013项目做一个系列的部署操作更新,希望能给即将在企业中部署的兄弟们有所帮助,在这个测试环境中,企业 前端池共…

Hello Playwright:(7)模拟键盘和鼠标

尽管在上一节中,我们已经能够通过FillAsync或ClickAsync来实现输入和点击元素。但是,还有其他场景,我们必须模拟用户使用键盘、鼠标与页面交互。例如在线文档:Page.Keyboard 对象Keyboard提供用于管理虚拟键盘的 API,它…