ISTIO文档解读学习(三)

                                      Istio安全

将单一应用程序分解为微服务可提供各种好处,包括更好的灵活性、可伸缩性以及服务复用的能力。但是,微服务也有特殊的安全需求:1)为了抵御中间人攻击,需要流量加密。2)为了提供灵活的服务访问控制,需要双向 TLS 和细粒度的访问策略。3)要审核谁在什么时候做了什么,需要审计工具。istio安全整体概述

ISTIO文档解读学习(三)_第1张图片

 

Istio 中的安全性涉及多个组件:1)Citadel 用于密钥和证书管理。2)Sidecar 和周边代理 实现客户端和服务器之间的安全通信。3)Pilot 将授权策咯和安全信息发给代理。4)Mixer 管理授权和审计

ISTIO文档解读学习(三)_第2张图片

上图Istio 安全架构。在服务间通信开始时,双方必须与其身份信息交换凭证以用于相互认证目的。在客户端,根据安全信息检查服务器的标识,以查看它是否是该服务的授权运行程序。在服务器端,服务器可以根据授权策略确定客户端可以访问哪些信息,审核谁在什么时间访问了什么,根据服务向客户收费并拒绝任何未能支付账单的客户访问服务。Istio 身份模型中,Istio 可以使用可以对服务实例进行分组的其他身份,例如服务名称。不同平台上的 Istio 服务标识:1)Kubernetes: Kubernetes 服务帐户。2)GKE/GCE: 可以使用 GCP 服务帐户。3)GCP: GCP 服务帐户。4)AWS: AWS IAM 用户/角色帐户。5)本地(非 Kubernetes): 用户帐户、自定义服务帐户、服务名称、Istio 服务帐户或 GCP 服务帐户。自定义服务帐户引用现有服务帐户,就像客户的身份目录管理的身份一样。

SPIFFE:一种标准,提供了一个框架规范,该框架能够跨异构环境引导和向服务发布身份。Istio 安全性和 SPIRE(是 SPIFFE 的实现)在 PKI 实现细节上有所不同。Istio 提供更全面的安全解决方案,包括身份验证、授权和审计。PKI:Istio PKI 建立在 Istio Citadel 之上,可为每个工作负载安全地提供强大的工作负载标识。Istio 使用 X.509 证书来携带 SPIFFE 格式的身份。PKI 还可用于大规模自动化密钥和证书轮换。Istio 支持在 Kubernetes pod 和本地计算机上运行的服务。目前每个方案使用不同的证书密钥配置机制。Kubernetes 方案: 1) Citadel 监视 Kubernetes apiserver,为每个现有和新的服务帐户创建 SPIFFE 证书和密钥对。Citadel 将证书和密钥对存储为Kubernetes secret。2) 创建 pod 时,Kubernetes 会根据其服务帐户通过Kubernetes secret volume 将证书和密钥对挂载到 pod 上。3) Citadel 监视每个证书的生命周期,并通过重写 Kubernetes secret 自动轮换证书。4) Pilot 生成安全命名信息,该信息定义了哪些 Service Account 可以运行哪些服务。Pilot 然后将安全命名信息传递给 envoy sidecar。

认证: Istio 提供两种类型的身份验证:传输身份验证,也称为服务间身份验证:验证建立连接的直接客户端。 Istio 提供双向TLS作为传输身份验证的完整堆栈解决方案。 无需更改服务代码即可打开此功能。这个解决方案:1)为每个服务提供强大的身份,表示其角色,以实现跨群集和云的互操作性。2)保护服务到服务通信和最终用户到服务的通信。3)提供密钥管理系统,以自动执行密钥和证书生成,分发和轮换。来源身份认证,也称为最终用户身份验证:验证作为最终用户或设备发出请求的原始客户端。Istio 通过 JSON Web Token(JWT)验证和 ORY HydraKeycloakAuth0Firebase AuthGoogle Auth 和自定义身份验证来简化开发人员体验,并且轻松实现请求级别的身份验证。在这两种情况下Istio都通过自定义 K8s API 将身份认证策略存储在 Istio 配置存储中。Pilot 会在适当的时候为每个代理保持最新状态以及密钥。此外Istio 支持在宽容模式(permissive mode)下进行身份验证,帮助了解策略更改在其生效之前如何影响安全状态。双向 TLS 认证:Istio 隧道通过客户端和服务器端进行服务间(service-to-service)通信Envoy代理。为了使客户端通过双向 TLS 调用服务端,遵循以下步骤:1、Istio 将出站流量从客户端重新路由到客户端的本地 sidecar Envoy。2、客户端 Envoy 与服务器端 Envoy 开始双向 TLS 握手。在握手期间,客户端 Envoy 还做了安全命名检查,以验证服务器证书中显示的服务帐户是否被授权运行到目标服务。3、客户端 Envoy 和服务器端 Envoy 建立了一个双向的 TLS 连接,Istio 将流量从客户端 Envoy 转发到服务器端 Envoy。4、授权后,服务器端 Envoy 通过本地 TCP 连接将流量转发到服务器服务。宽容模式:Istio 双向 TLS 具有一个宽容模式(permissive mode),允许 service 同时接受纯文本流量和双向 TLS 流量。这个功能极大的提升了双向 TLS 的入门体验。安全命名:安全命名信息包含从编码在证书中的服务器标识到被发现服务或 DNS 引用的服务名称的 N-到-N 映射。从身份 A 到服务名称 B 的映射意味着“允许 A 并授权其运行服务 B。Pilot 监视 Kubernetes apiserver,生成安全的命名信息,并将其安全地分发给 sidecar Envoy。

认证架构:网格操作者使用 .yaml 文件来指定策略。部署后策略将保存在 Istio 配置存储中。Pilot、Istio 控制器监视配置存储。一有任何的策略变更,Pilot 会将新策略转换为适当的配置,告知 Envoy sidecar 代理如何执行所需的身份验证机制。Pilot 可以获取公钥并将其附加到 JWT 验证配置。或者Pilot 提供 Istio 系统管理的密钥和证书的路径,并将它们挂载到应用程序 pod 以进行双向 TLS。Istio 异步发送配置到目标端点。代理收到配置后新的身份验证要求会立即生效。发送请求的客户端服务负责遵循必要的身份验证机制。对于源身份验证(JWT),应用程序负责获取 JWT 凭据并将其附加到请求。对于双向 TLS,Istio 提供目标规则。可以使用目标规则来指示客户端代理使用 TLS 与服务器端预期的证书进行初始连接。

ISTIO文档解读学习(三)_第3张图片

 

Istio 将两种类型的身份验证以及凭证中的其他声明(如果适用)输出到下一层:授权。此外可以指定将传输或原始身份验证中的哪个身份作为委托人使用。认证策略:认证策略是对服务收到的请求生效的,要在双向 TLS 中指定客户端认证策略,需要在 DetinationRule 中设置 TLSSettings。和其他的 Istio 配置一样,可以用 .yaml 文件的形式来编写认证策略,然后使用部署。策略存储范围:Istio 可以在命名空间范围或网络范围存储中存储身份认证策略,命名空间范围存储中的策略只能影响同一命名空间中的服务。网格范围内的策略可以影响网格中的所有服务。为防止冲突和滥用,只能在网格范围存储中定义一个策略。该策略必须命名为 default 并且有一个空的 targets: 部分。传输认证peers: 部分定义了策略中传输身份验证支持的身份验证方法和相关参数。该部分可以列出多个方法,并且只有一个方法必须满足认证才能通过。但是从 Istio 0.7 版本开始,当前支持的唯一传输身份验证方法是双向 TLS。默认的双向 TLS 模式为 STRICT。因此,mode: STRICT 等效于以下内容:- mtls:{}、- mtls: 、- mtls: null三种效果一样。如果不指定双向 TLS 模式,则对等方无法使用 Transport 身份验证,并且 Istio 拒绝绑定到 Sidecar 的双向 TLS 连接。在应用程序层,服务仍可以处理它们自己的双向 TLS 会话。来源身份认证:部署文件origins: 部分定义了原始身份验证支持的身份验证方法和相关参数。Istio 仅支持 JWT 原始身份验证。但是策略可以列出不同发行者的多个 JWT。与传输身份验证类似,要想通过身份验证必须通过其中的一个。

授权:Istio 的授权功能为 Istio 网格中的工作负载提供网格级别、命名空间级别和工作负载级别的访问控制。它提供了:1)工作负载间和最终用户到工作负载的授权。2)一个简单的 API,它包括一个单独的并且很容易使用和维护的AuthorizationPlicy CRD。3)灵活的语义,运维人员可以在 Istio 属性上自定义条件。4)高性能,因为 Istio 授权是在 Envoy 本地强制执行的。5)高兼容性,原生支持 HTTP、HTTPS 和 HTTP2,以及任意普通 TCP 协议。istio授权架构如下

ISTIO文档解读学习(三)_第4张图片

 

每个 Envoy 代理都运行一个授权引擎,该引擎在运行时授权请求。当请求到达代理时,授权引擎根据当前授权策略评估请求上下文,并返回授权结果 ALLOWDENY。无需显式启用 Istio 的授权功能,只需在工作负载上应用 AuthorizationPolicy 即可实现访问控制。如果没有对工作负载应用 AuthorizationPolicy,则不会执行访问控制,也就是说,将允许所有请求。如果有任何 AuthorizationPolicy 应用到工作负载,则默认情况下将拒绝对该工作负载的访问,除非策略中声明的规则明确允许了。目前,AuthorizationPolicy 仅支持 ALLOW 动作。 这意味着,如果将多个授权策略应用于同一工作负载,它们的效果是累加的。授权策略:要配置 Istio 授权策略,请创建一个 AuthorizationPolicy(AP) 资源。授权策略包括选择器和规则列表。 选择器指定策略所适用的目标,而规则指定什么条件下允许什么。 具体来说:目标AP里的 selector 部分, from 部分来源列表。什么 rule 中的 to 部分,操作列表。条件  rule 中的 when 部分。自定义条件列表。策略目标:策略范围(目标)由 metadata/namespace 和可选的 selector 确定。metadata/namespace 告诉该策略适用于哪个命名空间。如果设置为根命名空间,则该策略将应用于网格中的所有命名空间。根命名空间的值是可配置的,默认值为 istio-system。 如果设置为普通命名空间,则该策略将仅适用于指定的命名空间。工作负载 selector 可用于进一步限制策略的应用范围。 selector 使用 pod 标签来选择目标工作负载。 工作负载选择器包含 {key: value} 对的列表,其中 key 是标签的名称。 如果未设置,则授权策略将应用于与授权策略相同的命名空间中的所有工作负载。值匹配:大部分字段都支持完全匹配、前缀匹配、后缀匹配和存在匹配,但有一些例外情况(例如,when 部分下的key 字段,source 部分下的 ipBlocksto 部分下的 ports 字段仅支持完全匹配)。

在普通 TCP 协议上使用 Istio 授权:Istio 授权支持工作负载使用任意普通 TCP 协议,如 MongoDB。 在这种情况下,可以按照与 HTTP 工作负载相同的方式配置授权策略。 不同之处在于某些字段和条件仅适用于 HTTP 工作负载。 这些字段包括:1)授权策略对象 source 部分中的 request_principals 字段。2)授权策略对象 operation 部分中的 hostsmethodspaths 字段,如下列出了支持的条件。

名称 描述 支持的协议 示例
request.headers HTTP 请求头,需要用 [] 括起来 HTTP only key: request.headers[User-Agent]
values: ["Mozilla/*"]
source.ip IP 地址,支持单个 IPCIDR HTTP and TCP key: source.ip
values: ["10.1.2.3"]
source.namespace 源负载实例命名空间,需启用双向 TLS HTTP and TCP key: source.namespace
values: ["default"]
source.principal 源负载的标识,需启用双向 TLS HTTP and TCP key: source.principal
values: ["cluster.local/ns/default/sa/productpage"]
request.auth.principal 已认证过 principal 的请求。 HTTP only key: request.auth.principal
values: ["accounts.my-svc.com/104958560606"]
request.auth.audiences 此身份验证信息的目标主体 HTTP only key: request.auth.audiences
values: ["my-svc.com"]
request.auth.presenter 证书的颁发者 HTTP only key: request.auth.presenter
values: ["123456789012.my-svc.com"]
request.auth.claims Claims 来源于 JWT。需要用 [] 括起来 HTTP only key: request.auth.claims[iss]
values: ["*@foo.com"]
destination.ip 目标 IP 地址,支持单个 IPCIDR HTTP and TCP key: destination.ip
values: ["10.1.2.3", "10.2.0.0/16"]
destination.port 目标 IP 地址上的端口,必须在 [0,65535] 范围内 HTTP and TCP key: destination.port
values: ["80", "443"]
connection.sni 服务器名称指示,需启用双向 TLS HTTP and TCP key: connection.sni
values: ["www.example.com"]
experimental.envoy.filters.* 用于过滤器的实验性元数据匹配,包装的值 [] 作为列表匹配 HTTP and TCP key: experimental.envoy.filters.network.mysql_proxy[db.table]
values: ["[update]"]

对双向 TLS 的依赖:Istio 使用双向 TLS 将某些信息从客户端安全地传递到服务器。在使用授权策略中的以下任何字段之前,必须先启用双向 TLS:1) source 部分下的 principals 字段,2)source部分下的 namespaces 字段。3)source.principal 自定义条件。4)source.namespace自定义条件。5)connection.sni自定义条件。如果不使用授权策略中的上述任何字段,则双向 TLS 不是必须的。

你可能感兴趣的:(微服务学习)