Skip to content

6、Istio安全

6、Istio 安全

img

目录

image-20231125080337605

[toc]

本节实战

实战名称
🚩 实战:对等认证(默认的宽容模式)-2023.11.24(测速成功)
🚩 实战:对等认证(全局严格 mTLS 模式)-2023.11.24(测速成功)
🚩 实战:对等认证(命名空间级别策略)-2023.11.24(测速成功)
🚩 实战:对等认证(为每个工作负载启用双向 TLS)-2023.11.24(测速成功)
🚩 实战:对等认证(为每个端口配置不同的对等认证策略)-2023.11.24(测速成功)
🚩 实战:请求认证-2023.11.25(测试成功)
🚩 实战:HTTP 请求授权-20223.11.27(测试成功)
🚩 实战:TCP 请求授权-20223.11.28(测试成功)

1、安全概述

安全是一个非常重要的话题,但也是平时容易被忽略的一个话题,我们在开发应用的时候,往往会忽略安全,但是当应用上线后,安全问题就会暴露出来,这时候就会造成很大的损失。Istio 通过在服务之间注入 Sidecar 代理,来实现对服务之间的流量进行控制和监控,从而实现服务之间的安全通信。

接下来我们将从**证书管理、认证、授权**等几个方面来学习 Istio 的安全机制。

将单一应用程序拆分为微服务可提供各种好处,包括更好的灵活性、可伸缩性以及服务复用的能力。但是,微服务也有特殊的安全需求:

  • 为了抵御中间人攻击,需要流量加密。
  • 为了提供灵活的服务访问控制,需要双向 TLS 和细粒度的访问策略。
  • 要确定谁在什么时候做了什么,需要审计工具。

Istio 尝试提供全面的安全解决方案来解决所有这些问题,Istio 安全性可以减轻针对你的数据、端点、通信和平台的内外威胁。

img

Istio 为微服务提供了无侵入,可插拔的安全框架。应用不需要修改代码,就可以利用 Istio 提供的双向 TLS 认证实现服务身份认证,并基于服务身份信息提供细粒度的访问控制。Istio 安全的高层架构如下图所示:

img

上图展示了 Istio 中的服务认证授权两部分。服务认证是通过控制面和数据面一起实现的:

  • 控制面:Istiod 中实现了一个 CA (Certificate Authority,证书机构) 服务器。该 CA 服务器负责为网格中的各个服务签发证书,并将证书分发给数据面的各个服务的边车代理。
  • 数据面:在网格中的服务相互之间发起 plain(原始的,未加密的) HTTP/TCP 通信时,和服务同一个 pod 中的边车代理会拦截服务请求,采用证书和对端服务的边车代理进行双向 TLS 认证并建立一个 TLS 连接,使用该 TLS 连接来在网络中传输数据。

Istio 的授权功能为网格中的工作负载提供网格、命名空间和工作负载级别的访问控制,这种控制层级提供了许多优点:

  • 工作负载到工作负载以及最终用户到工作负载的授权。
  • 一个简单的 API:它包括一个单独的并且很容易使用和维护的 AuthorizationPolicyCRD。
  • 灵活的语义:运维人员可以在 Istio 属性上定义自定义条件,并使用 DENYALLOW动作。
  • 高性能:Istio 授权是在 Envoy 本地强制执行的。
  • 高兼容性:原生支持 HTTP、HTTPS 和 HTTP2,以及任意普通 TCP 协议。

**授权策略对服务器端 Envoy 代理的入站流量实施访问控制。**每个 Envoy 代理都运行一个授权引擎,该引擎在运行时授权请求。当请求到达代理时,授权引擎根据当前授权策略评估请求上下文,并返回授权结果 ALLOWDENY。运维人员可以通过 YAML 资源清单文件来指定 Istio 授权策略。

2、证书签发流程

默认情况下,Istio CA 生成自签名根证书和密钥,并使用它们来签署工作负载证书。为了保护根 CA 密钥,我们应该使用在安全机器上离线运行的根 CA(比如使用 Hashicorp Vault进行管理),并使用根 CA 向每个集群中运行的 Istio CA 颁发中间证书。Istio CA 可以使用管理员指定的证书和密钥对工作负载证书进行签名,并将管理员指定的根证书作为信任根分发给工作负载。

img

1.签发证书

当我们有了 Istio CA 根证书后就可以使用它来签发工作负载证书了,那么整个的证书签发流程又是怎样的呢?如下图所示:

img

  • Envoy 向 pilot-agent发起一个 SDS (Secret Discovery Service)请求(启动的时候),要求获取自己的证书和私钥。
  • pilot-agent生成私钥和 CSR 证书签名请求,向 Istiod 发送证书签发请求,请求中包含 CSR 和该 Pod 中服务的身份信息。
  • Istiod 提供 gRPC 服务以接受证书签名请求,根据请求中服务的身份信息(如果是 Kubernetes 则使用 Service Account)为其签发证书,将证书返回给 pilot-agent
  • pilot-agent将证书和私钥通过 SDS 接口返回给 Envoy。
  • pilot-agent还会监控工作负载证书的过期时间,上述过程会定期重复进行证书和密钥轮换。

这个流程和我们自己用手动方式去进行证书签发是一样的,所以我们需要先了解下证书签发的流程。Istio CA 根证书就是一个证书颁发机构,平时如果要为我们自己的网站申请 HTTPS 证书我们也是去一些正规的 CA 机构进行申请,而这个申请的信息就是生成的 CSR 证书签名请求,然后我们将这个 CSR 和身份信息提交给 CA 机构,CA 机构根据这些信息为我们签发证书,然后我们就可以使用这个证书了,只是我们这里在不同的组件上来执行这些操作,整体流程是一样的。

istio-ca-root-cert

bash
[root@master1 ~]#kubectl get cm -nistio-systemNAMEDATAAGE……istio-ca-root-cert115d……[root@master1 ~]#[root@master1 ~]#kubectl get po istiod-644f5d55fc-gs96f -nistio-system -oyaml……-mountPath:/var/run/secrets/istiod/caname:istio-csr-ca-configmapreadOnly:true……-configMap:defaultMode:420name:istio-ca-root-certoptional:truename:istio-csr-ca-configmap

image-20231123122545714

2.身份认证

另外要通过服务证书来实现网格中服务的身份认证,必须首先确保服务从控制面获取自身证书的流程是安全的。Istio 通过 Istiod 和 pilog-agent之间的 gRPC 通道传递 CSR 和证书,因此在这两个组件进行通信时,双方需要先验证对方的身份,以避免恶意第三方伪造 CSR 请求或者假冒 Istiod CA 服务器。Istio 中主要包含下面两种认证方式:

  • Istiod 身份认证

    • Istiod 采用其内置的 CA 服务器为自身签发一个服务器证书,并采用该服务器证书对外提供基于 TLS 的 gPRC 服务。

    • Istiod 调用 Kubernetes APIServer 生成一个名为 istio-ca-root-cert的 ConfigMap 对象, 在该 ConfigMap 中放入了 Istiod 的 CA 根证书。

    • 该 ConfigMap 被 Mount 到 istio-proxy容器中,被 pilot-agent用于验证 Istiod 的服务器证书。

    • pilot-agent和 Istiod 建立 gRPC 连接时,pilot-agent采用标准的 TLS 服务器认证流程对 Istiod 的服务器证书进行认证。

  • pilot-agent 身份认证

    • 在 Kubernetes 中可以为每一个 Pod 关联一个 ServiceAccount,以表明该 Pod 中运行的服务的身份信息。

    • Kubernetes 会为该 ServiceAccount 生成一个 jwt token,并将该 token 通过 secret 加载到 pod 中的一个文件。

    • pilot-agent在向 Istiod 发送 CSR 时,将其所在 Pod 的 service account token 也随请求发送给 Istiod。

    • Istiod 调用 Kube-apiserver 接口验证请求中附带的 service account token,以确认请求证书的服务身份是否合法。

这里需要注意的是不同版本的 Kubernetes 集群下面的 ServiceAccount Token 生成方式并不一样,但最终都是通过改 Token 来进行身份认证的。

  • 1.20(含 1.20)之前的版本,在创建 sa 时会自动创建一个 secret,然后这个会把这个 secret 通过投射卷挂载到 pod 里,该 secret 里面包含的 token 是永久有效的。
  • 1.21~1.23 版本,在创建 sa 时也会自动创建 secret,但是在 pod 里并不会使用 secret 里的 token,而是由 kubelet 到 TokenRequest API 去申请一个 token,该 token 默认有效期为一年,但是 pod 每一个小时会更新一次 token。
  • 1.24 版本及以上,在创建 sa 时不再自动创建 secret 了,只保留由 kubelet 到 TokenRequest API 去申请 token。

3、认证

Istio 提供两种类型的认证用于管控网格服务间的双向 TLS 和终端用户的身份认证。:

  • 对等认证:用于服务到服务的认证,以验证建立连接的客户端。Istio 提供双向 TLS 作为传输认证的全栈解决方案,无需更改服务代码就可以启用它。这个解决方案:

    • 为每个服务提供代表其角色的强大身份,以实现跨集群和云的互操作性。

    • 确保服务间通信的安全。

    • 提供密钥管理系统,以自动进行密钥和证书的生成、分发和轮换。

  • 请求认证:用于终端用户认证,以验证附加到请求的凭据。Istio 使用 JSON Web Token(JWT)验证启用请求级认证,并使用自定义认证实现或任何 OpenID Connect的认证实现来简化的开发人员体验。

1.对等认证

a.默认的宽容模式

🚩 实战:对等认证(默认的宽容模式)-2023.11.24(测速成功)

实验环境:

bash
k8sv1.27.6(containerd:istiov1.19.3(--setprofile=demo)

实验软件:

链接:https:kubectlapply-f<(istioctlkube-inject -fsamples/httpbin/httpbin.yaml)-nfookubectlapply-f<(istioctlkube-inject -fsamples/sleep/sleep.yaml)-nfookubectlcreatensbarkubectlapply-f<(istioctlkube-inject -fsamples/httpbin/httpbin.yaml)-nbarkubectlapply-f<(istioctlkube-inject -fsamples/sleep/sleep.yaml)-nbarkubectlcreatenslegacykubectlapply-fsamples/httpbin/httpbin.yaml-nlegacykubectlapply-fsamples/sleep/sleep.yaml-nlegacy

查看:

现在可以在 foobarlegacy三个命名空间下的任意 sleep Pod 中使用 curl 向 httpbin.foohttpbin.barhttpbin.legacy发送 HTTP 请求来验证部署结果,所有请求都应该成功并返回 HTTP 200。

这样保证了我们的服务之间是可以互相访问的。

接下来我们就来看下如何对服务进行认证。