为什么 Istio 要使用 SPIRE 做身份认证?

标签: istio spire 身份认证 | 发表时间:2022-06-21 19:27 | 作者:
出处:https://jimmysong.io/blog/

今年 6 月初, Istio 1.14 发布 ,该版本中最值得关注的特性是新增对 SPIRE 的支持。 SPIFFE 和 SPIRE 都是 CNCF 孵化项目,其中 SPIRE 是 SPIFFE 的实现之一。本文将带你了解 SPIRE 对于零信任架构的意义,以及 Istio 是为何使用 SPIRE 实现身份认证。

Kubernetes 中的身份认证

我们都知道 Istio 最初是基于 Kubernetes 建立起来的,在谈在 Istio 中使用 SPIRE 做身份认证之前,我们先来看下 Kubernetes 中如何做身份认证。

我们来看一个 pod 的 token 的例子,下面是 default 命名空间下 sleep pod 的 Service Account 的 token。

   apiVersion: v1
data:
  ca.crt: {CA_CRT}
  namespace: ZGVmYXVsdA==
  token: {TOKEN_STRING}
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: sleep
    kubernetes.io/service-account.uid: 2c0d00e8-13a2-48d0-9ff8-f987f3325ecf
  creationTimestamp: "2022-06-14T03:01:35Z"
  name: sleep-token-gwhwd
  namespace: default
  resourceVersion: "244535398"
  uid: b8822ceb-9553-4a17-96dc-d525bbaed0e0
type: kubernetes.io/service-account-token

我们看到其中有 ca.crttoken 字段,如果这个 token 被窃取,会有什么后果?Kubernetes 中使用 Service Account 来管理 Pod 的身份,然后利用 RBAC 指定具有某 Service Account 的 Pod 对 Kubernetes API 的权限。Service Account 的 token 存储在 Secret 中,token 中并不包含工作负载所运行的节点、pod 的声明,一旦 token 被窃取破坏者就获得了该账户的所有权限,伪装成该用户窃取信息或破坏。

一个 token 只能在一个集群中标记负载身份,Istio 同时支持 Kubernetes 环境和虚拟机,还有多集群多网格,如何统一这些异构环境中的工作负载身份?这时,一个统一的工作负载身份标准就呼之欲出了。

SPIFFE 与 SPIRE 简介

SPIFFE 的目的是基于零信任的理念,建立一个开放、统一的工作负载身份标准,这有助于建立一个零信任的全面身份化的数据中心网络。SPIFFE 的核心是通过简单 API 定义了一个短期的加密身份文件 SVID,用作工作负载认证时使用的身份文件,例如建立 TLS 连接或签署和验证 JWT 令牌等。SPIRE 可以根据管理员定义的策略自动轮换 X.509 SVID 证书和秘钥。Istio 可以通过 SPIRE 动态的消费工作负载标识,SPIRE 可以动态的提供工作负载标识。

下面我将为你简单介绍一下与 SPIFFE 相关的一些术语。

  • SPIFFE(Secure Production Identity Framework For Everyone)是一套身份认证标准。
  • SPIRE(SPIFFE Runtime Environment) 是 SPIFFE 标准的一套生产就绪实现。
  • SVID(SPIFFE Verifiable Identity Document)是工作负载向资源或调用者证明其身份的文件。SVID 包含一个 SPIFFE ID,代表了服务的身份。它将 SPIFFE ID 编码在一个可加密验证的文件中,目前支持两种格式:X.509 证书或 JWT 令牌。
  • SPIFFE ID 是一个统一资源标识符(URI),其格式如下: spiffe://trust_domain/workload_identifier

SPIRE 包含 Server 和 Agent 两个部分,它们的作用如下。

SPIRE Server

  • 身份映射
  • 节点认证
  • SVID 颁发

SPIRE Agent

  • 工作负载认证
  • 提供工作负载 API

SPIFFE 与零信任安全

零信任的本质是以身份为中心的动态访问控制。动态证书轮换、动态证书下发、动态权限控制。SPIFFE 解决的是标识工作负载的问题。

在虚拟机时代我们可能根据一个 IP 地址和端口来标识一个工作负载,基于 IP 地址标识存在多个服务共享一个 IP 地址,IP 地址伪造和访问控制列表过大等问题。到了 Kubernetes 时代,容器的生命周期是短暂的,我们无法再用 IP 地址来标识负载,而是通过 pod 或 service 名称。但是,不同的云、软件平台对工作负载标识的方法不同,相互之间存在兼容性问题。尤其是在异构混合云的中,同时存在虚拟机和容器的工作负载。这时,建立一个细粒度、具有互操作性的标识系统,将具有重要意义。

在 Istio 中使用 SPIRE 做身份认证

Istio 会利用 SPIRE 为每个工作负载提供一个唯一标识,服务网格中的工作负载在进行对等身份认证、请求身份认证和授权策略都会使用到服务标识,用于验证访问是否被允许。SPIRE 原生支持 Envoy SDS API,SPIRE Agent 中的通过与工作负载中共享的 UNIX Domain Socket 通信,为工作负载颁发 SVID。请参考 Istio 文档 了解如何在 Istio 中使用 SPIRE 做身份认证。

SDS 最重要的好处就是简化了证书管理。如果没有这个特性,在 Kubernetes deployment 中,证书就必须以 secret 的方式被创建,然后挂载进代理容器。如果证书过期了,就需要更新 secret 且代理容器需要被重新部署。如果使用 SDS,Istio 可以使用 SDS 服务器会将证书推送给所有的 Envoy 实例。如果证书过期了,服务器仅需要将新证书推送至 Envoy 实例,Envoy 将会立即使用新证书且不需要重新部署代理容器。

下图展示了 Istio 中使用 SPIRE 进行身份认证的架构。

Istio 中使用 SPIRE 进行身份认证的架构图 Istio 中使用 SPIRE 进行身份认证的架构图

在 Kubernetes 集群中的 spire 命名空间中使用 StatefulSet 部署 SPIRE Server 和 Kubernetes Workload Registrar,使用 DaemonSet 资源为每个节点部署一个 SPIRE Agent。假设你在安装 Kubernetes 时使用的是默认的 DNS 名称 cluster.localKubernetes Workload Registar 会为 Istio Mesh 中的工作负载创建如下格式的身份:

  • SPRRE Server: spiffe://cluster.local/ns/spire/sa/server
  • SPIRE Agent: spiffe://cluster.local/ns/spire/sa/spire-agent
  • Kubernetes Node: spiffe://cluster.local/k8s-workload-registrar/demo-cluster/node/
  • Kubernetes Worload Pod: spiffe://cluster.local/{namespace}/spire/sa/{service_acount}

这样不论是节点还是每个工作负载都有它们全局唯一的身份,而且还可以根据集群 (信任域)扩展。

Istio Mesh 中的工作负载身份验证过程如下图所示。

图片 Istio 服务网格中的工作负载身份认证过程示意图

详细过程如下:

  1. 工作负载的 sidecar 中的 pilot-agent 会通过共享的 UDS 调用 SPIRE Agent 来获取 SIVD
  2. SPIRE Agent 询问 Kubernetes(准确的说是节点上的 kubelet)获取负载的信息
  3. Kubelet 将从 API server 查询到的信息返回给工作负载验证器
  4. 验证器将 kubelet 返回的结果与 sidecar 共享的身份信息比对,如果相同,则将正确的 SVID 缓存返回给工作负载

关于工作负载的注册和认证的详细过程请参考 SPIRE 文档

总结

身份是零信任网络的基础,SPIFFE 统一了异构环境下的身份标准。在 Istio 中不论我们是否使用 SPIRE,身份验证对于工作负载来说是不会有任何感知的。通过 SPIRE 来为工作负载提供身份验证,可以有效的管理工作负载的身份,为实现零信任网络打好基础。

相关 [istio spire 身份认证] 推荐:

为什么 Istio 要使用 SPIRE 做身份认证?

- - Jimmy Song - 宋净超的个人博客 – 博客
今年 6 月初, Istio 1.14 发布 ,该版本中最值得关注的特性是新增对 SPIRE 的支持. SPIFFE 和 SPIRE 都是 CNCF 孵化项目,其中 SPIRE 是 SPIFFE 的实现之一. 本文将带你了解 SPIRE 对于零信任架构的意义,以及 Istio 是为何使用 SPIRE 实现身份认证.

网络数字身份认证术

- - 酷 壳 – CoolShell
这篇文章是《 HTTP API 认证授权术》的姊妹篇,在那篇文章中,主要介绍了 HTTP API 认证和授权技术中用到的 HTTP Basic, Digest Access, HMAC, OAuth, JWT 等各种方式,主要是 API 上用到的一些技术,这篇文章主要想说的是另一个话题——身份认证.

istio 原理简介

- - 掘金 架构
由于 istio 自 1.5 版本以后架构上有了较大变化,控制面从多组件变成了单体的 istiod 组件,所以下文会先介绍 1.5 之前的架构,再介绍 1.5 之后的,是一个由繁到简的过程. istio 1.5 之前架构. Istio 的架构分为控制平面和数据平面. 数据平面:由一组智能代理(Envoy)以 sidecar 模式部署,协调和控制所有服务之间的网络通信.

身份认证设计的基本准则

- - ITeye博客
密码认证作为当前最流行的身份验证方式,在安全方面最值得考虑的因素就是密码的长度. 一个强度高的密码使得人工猜测或者暴力破解密码的难度增加. 下面定义了高强度密码的一些特性. 对于重要的应用,密码长度最少为6;对于关键的应用,密码长度最少为8;对于那些最关键的应用,应该考虑多因子认证系统. 有的时候仅有长度约束是不够的,比如说12345678、11111111这样的密码,长度的确是8位,但极容易被猜测和字典攻击,所以这时候就需要增加密码复杂度.

教育信息化、信息孤岛与身份认证

- - writing for time
最近接触的项目和需求中,统一身份认证的问题反复出现,花了不少功夫去了解身份认证这块相关的标准和协议. 身份认证/授权这部分涉及的概念真是五花八门,一度把我搞得七荤八素,相关概念包括但不限于:session,cookie,OpenID,OAuth2,CAS,JWT,SSO,Token,SAML,Shibboleth(以上这些概念并不都在同一层面).

聚焦安全:互联网场景的身份认证方法分析

- - 技术改变世界 创新驱动中国 - 《程序员》官网
2011年末多家国内网站用户信息泄露,让许多人意识到安全不再是与自己无关的话题. 2012年3月《程序员》封面报道,我们分别从身份认证、数据库安全、中间平台、终端用户、云计算等几个角度为大家剖析安全所涉的方方面面. 身份认证是一个古老的话题,从最早的户籍造册,到今天的2代身份证或社会保险号码,“我是谁”或“他是谁”的问题贯穿着人类社会的发展.

Istio 常见的 10 个异常分析

- - DockOne.io
本文总结了使用 Istio 常见的 10 个异常. Istio 支持多平台,不过 Istio 和 Kubernetes 的兼容性是最优的,不管是设计理念,核心团队还是社区, 都有一脉相承的意思. 但 Istio 和 Kubernetes 的适配并非完全没有冲突,一个典型问题就是 Istio 需要 Kubernetes Service 按照协议进行端口命名(Port Naming).

Istio究竟是干嘛的? - 知乎

- -
当微服务架构体系越来越复杂的时候,需要将“业务服务”和“基础设施”解耦,将一个微服务进程一分为二:. 一个进程实现业务逻辑,biz,即上图白色方块. 一个进程实现底层技术体系,proxy,即上图蓝色方块,负载均衡、监控告警、服务发现与治理、调用链…等诸多基础设施,都放到这一层实现. biz不管是调用服务,还是提供服务,都只与本地的proxy进行本地通信.

使用 Istio 进行金丝雀部署

- -
本篇博客最后更新时间 2018 年 5 月 16 号,采用了最新版本的流量管理模型. Istio项目的一大好处就是为服务金丝雀方式部署提供了控制便利. 金丝雀部署(或上线)背后的想法是通过让一小部分用户流量引入的新版本进行测试,如果一切顺利,则可以增加(可能逐渐增加)百分比,逐步替换旧版本. 如在过程中出现任何问题,则可以中止并回滚到旧版本.

实践k8s istio熔断 - fat_girl_spring - 博客园

- -
熔断主要是无感的处理服务异常并保证不会发生级联甚至雪崩的服务异常. 在微服务方面体现是对异常的服务情况进行快速失败,它对已经调用失败的服务不再会继续调用,如果仍需要调用此异常服务,它将立刻返回失败. 与此同时,它一直监控服务的健康状况,一旦服务恢复正常,则立刻恢复对此服务的正常访问. 这样的快速失败策略可以降低服务负载压力,很好地保护服务免受高负载的影响.