istio-身份认证(Authentication)

在Istio中,提供了两种身份验证模式,这两种方式是传输身份验证和原始身份验证。

  • 传输身份验证,也称为服务到服务身份验证:验证建立直接连接的客户端。Istio提供双向TLS(mutual TLS)作为用于传输身份验证的完整堆栈解决方案。在Istion中可以轻松启用此功能,而无需更改服务代码。此解决方案:
  • 为每个服务提供一个强大的标识,以表示其角色,以实现跨集群和云的互操作性。
  • 保证服务到服务和最终用户到服务通信的安全。
  • 提供密钥管理系统,以自动进行密钥和证书的生成、分发和轮换。
  • 原始身份验证,也称为终端用户身份验证:将发出请求的原始客户端验证为最终用户或设备。Istio通过JSON Web令牌(JWT)验证启用请求级身份验证,并为开发人员提供使用OpenID Connect提供者(ORY Hydra,Keycloak,Auth0, Firebase Auth, Google Auth)和自定义身份验证的简化经验 。

在这两种情况下,Istio都会通过自定义的Kubernetes API在Istio config store存储身份验证策略。Pilot可以使每个代理服务器保持最新状态,并在适当时提供密钥。

1 双向TLS身份验证

Istio通过客户端和服务器端的Envoy代理建立服务到服务的通信通道。为使客户端通过双向TLS身份验证调用服务器端:

  • Istio将来自客户端的出站流量重新路由到客户端的本地Sidecar Envoy。
  • 客户端Envoy与服务器端Envoy开始双向TLS握手。在握手期间,客户端Envoy还会进行安全的命名检查,以验证服务器证书中提供的服务帐户是否有权运行目标服务。
  • 客户端Envoy和服务器端Envoy建立双向TLS连接,Istio将流量从客户端Envoy转发到服务器端Envoy。
  • 授权后,服务器端Envoy通过本地TCP连接将流量转发到服务器服务。

Istio双向TLS具有许可模式,该模式允许服务同时接受纯文本和双向TLS流量。此功能极大地改善了双向TLS的体验。与非Istio服务器通信的许多非Istio客户端给想要将服务器迁移到启用了TLS的Istio的操作员带来了问题。通常,操作员无法同时为所有客户端安装Istio sidecar,甚至没有权限在某些客户端上安装。即使在服务器上安装了Istio Sidecar之后,操作员也无法在不中断现有通信的情况下启用双向TLS。

启用许可模式后,服务器将接受纯文本和双向TLS流量。该模式为注册过程提供了极大的灵活性。服务器安装的Istio Sidecar会立即获取相互TLS流量,而不会破坏现有的纯文本流量。因此,运营商可以逐步安装和配置客户端的Istio边车,以发送相互的TLS流量。一旦完成客户端的配置,操作员就可以将服务器配置为仅TLS双向模式。

2 认证架构

在Istio网格中,可以使用身份验证策略为接收请求的服务指定身份验证要求。在网格运算符中,使用.yaml 文件来指定策略。部署后,策略将被保存在Istio配置存储,。Pilot作为Istio的控制器负责监视配置存储。在任何策略更改后,Pilot都会将新策略转换为适当的配置,以告诉Envoy Sidecar代理如何执行所需的身份验证机制。Pilot可以获取公共密钥,并将其附加到配置中以进行JWT验证。另外,Pilot提供了Istio系统管理的密钥和证书的路径,并将它们安装到应用程序容器中以实现相互TLS。Istio将配置异步的发送到目标端点。代理收到配置后,新的身份验证要求将立即在该容器上生效。

客户端服务(发送请求的服务)负责遵循必要的身份验证机制。对于原始身份验证(JWT),应用程序负责获取JWT凭证并将其附加到请求。对于双向TLS,Istio提供了目标规则。运算符使用目标规则,来指示客户端代理使用TLS(带有服务器端预期的证书)进行初始连接。

认证架构

Istio将身份验证与身份验证的类型以及证书中的其他声明(如果适用)一起输出到下一层: 访问授权(authorization)。此外,运算符可以指定在Istio中作为“主体”的身份(通过传输身份验证或原始身份验证)。

3 认证策略

本节提供有关Istio身份验证策略如何工作的更多详细信息。与其它Istio配置一样,可以在.yaml文件中指定身份验证策略 。如果使用的平台是Kubernetes,则可以使用kubectl部署策略。

在下面的示例中,身份验证策略指定reviews服务的传输身份验证必须使用双向TLS:

#——-设置reviews服务的身份认证策略—

apiVersion: “authentication.istio.io/v1alpha1”

kind: “Policy”

metadata:

name: “reviews”

spec:

targets:

– name: reviews

peers:

– mtls: {}

表 认证策略字段

领域 类型 描述 需要
targets TargetSelector[] 列出策略所选择的应用。如果值为空,则将对同一名称空间中的所有工作负载使用此策略。
peers PeerAuthenticationMethod[] 用于对等身份验证的验证方法列表。

如果不需要对等身份验证,请将列表留空

peerIsOptional bool 值为true即可接受请求(从对等身份验证的角度来看),即使都不满足上述定义的任何对等身份验证方法。

通常,用于将拒绝决策延迟到下一层(例如,授权)。

如果没有为对等定义身份验证(对等字段为空),则忽略此标志。

origins OriginAuthenticationMethod[] 可用原始身份验证的验证方法列表。如果不需要原始身份验证,请将列表留空。
originIsOptional bool 值为true即可接受请求(对于原始身份验证而言),即使都不满足以上定义的所有原始身份验证方法。

通常,用于将拒绝决策延迟到下一层(例如,授权)。

如果没有为源定义身份验证(源字段为空),则忽略此标志。

principalBinding PrincipalBinding 定义应使用对等身份还是原始身份作为主体。

默认值为USE_PEER。如果由于未定义对等/原始身份验证或失败而导致对等(或原始)身份不可用,则主体将保持不变。换句话说,约束规则不影响接受或拒绝请求的决定。

1.1.3.1     策略应用范围

Istio可以将身份验证策略存储在名称空间范围或网格范围的存储中。

  • 网格范围的策略通过指定kind字段的值为”MeshPolicy”,以及设置策略名称为”default”。例如:

apiVersion: “authentication.istio.io/v1alpha1”

kind: “MeshPolicy”

metadata:

name: “default”

spec:

peers:

– mtls: {}

  • 命名空间范围的策略通过指定kind 字段的值为”Policy”,以及指定一个命名空间。如果未指定,则使用默认名称空间,此示例中的命名空间为ns1。

apiVersion: “authentication.istio.io/v1alpha1”

kind: “Policy”

metadata:

name: “default”

namespace: “ns1”

spec:

peers:

– mtls: {}

命名空间范围存储的策略只会影响本名称空间中的服务。网格范围存储的策略会影响网格中的所有服务。为了防止冲突和滥用,只能在网格范围定义一个策略。该策略必须命名为default,并具有 空值的targets:。在Kubernetes中,通过自定义资源(CRD)实现Istio配置。这些CRD对应于命名空间范围和集群范围,CRDs通过Kubernetes RBAC自动继承访问保护。

1.1.3.2     目标选择器

身份验证策略的目标指定该策略适用的一个或多个服务。以下示例指定该策略适用于:

  • product-page服务的任何端口。
  • reviews服务的9000端口。

targets:

– name: product-page

– name: reviews

ports:

– number: 9000

如果未提供targets,则Istio会将策略与策略所在存储范围内的所有服务进行匹配。因此,通过targets可以指定策略的应用范围:

  • 网格范围的策略:在网格范围定义,并且没有目标选择器,这种策略只能设置一个。
  • 命名空间范围的策略:在命名空间范围定义的策略,策略名称为default,并且没有目标选择器。每个命名空间最多可以定义一个命名空间范围的策略。
  • 特定服务的策略:在命名空间定义的策略,带有非空的目标选择器。名称空间可以定义多个特定服务的策略。

对于每种服务,Istio都会应用最窄的匹配策略。优先顺序为: 特定服务的策略>命名空间范围的策略>网格范围的策略。如果存在一个以上特定服务的策略与服务匹配,则Istio会随机选择其中之一,在配置其策略时必须避免此类冲突。

为了对网格范围和命名空间范围的策略强制唯一性,Istio每个网格仅接受一个身份验证策略,每个命名空间仅接受一个身份验证策略。Istio还要求网状范围和命名空间范围的策略的名称为default。如果服务没有匹配的策略,则会禁用传输身份验证和原始身份验证。

表 目标选择器字段

领域 类型 描述 需要
name string 该名称必须是服务在注册表中的简称。
ports PortSelector[] 指定端口。请注意,这是服务暴露的端口,而不是工作负载实例端口。例如,如果服务定义如下,8000则应使用而不是9000。

kind: Service

metadata:

spec:

ports:

– name: http

port: 8000

targetPort: 9000

selector:

app: backend

如果端口值为空,则匹配所有暴露的端口。

1.1.3.3     传输认证

Peers用于定义支持传输身份验证的验证方法和相关参数。从Istio 0.7版本开始,只支持双向TLS这种唯一的传输身份验证方法。

以下示例显示了peers使用双向TLS的传输身份验证。

peers:

– mtls: {}

相互TLS设置具有一个可选mode参数,该参数定义对等传输身份验证的严格性。默认的双向TLS模式为STRICT。因此,mode: STRICT等效于以下所有:

  • mtls: {}
  • mtls:
  • mtls: null

如果不指定双向TLS模式,则对等方无法使用传输身份验证,并且Istio拒绝绑定到Sidecar的双向TLS连接。在应用程序层,服务仍可以处理它们自己的相互TLS会话。

1.1.3.4     原始身份验证

origins定义了源身份验证支持的验证方法和相关参数。Istio仅支持JWT原始身份验证。可以指定允许的JWT颁发者,并为特定路径启用或禁用JWT身份验证。如果为请求路径禁用了所有JWT,则身份验证也会通过,就像没有定义任何身份验证一样。与对等身份验证类似,只有且只满足一种列出的方法必须才能通过身份验证。

以下示例中,策略指定了用于原始身份验证,该部分接受Google发出的JWT。路径的JWT身份验证/health已禁用。

origins:

– jwt:

issuer: “https://accounts.google.com”

jwksUri: “https://www.googleapis.com/oauth2/v3/certs”

trigger_rules:

– excluded_paths:

– exact: /health

1.1.3.5     主体绑定

主体绑定键值对定义策略的主体。默认情况下,Istio使用peers配置的身份验证。如果peers未配置身份验证,则Istio会将身份验证保留为未设置状态。策略编写者可以使用USE_ORIGIN值覆盖此行为。此值将Istio配置为使用源身份验证作为主体身份验证。将来,将支持条件绑定,例如:USE_PEER当peer为X时,否则为 USE_ORIGIN。

以下示例显示principalBinding的值 USE_ORIGIN:

principalBinding: USE_ORIGIN

名称 描述
USE_PEER 主体将被设置为来自对等身份验证的身份。
USE_ORIGIN 主体将被设置为来自原始身份验证的身份。

4 更新身份验证策略

可以随时更改身份验证策略,Istio几乎实时地将更改推送到端点。但是,Istio无法保证所有端点都同时收到新策略。以下是在更新身份验证策略时避免中断的建议:

  • 要启用或禁用双向TLS:使用带有mode: PERMISSIVE临时策略。这将接收服务配置为能够接受两种类型的流量:纯文本和TLS。因此,没有请求将会被丢弃。一旦所有客户端切换到预期的协议,无论是否具有相互TLS,都可以用最终策略将PERMISSIVE策略替换掉。

peers:

– mtls:

mode: PERMISSIVE

  • 对于JWT身份验证迁移:更改策略之前,请求应包含新的JWT。服务器端完全切换到新策略后,可以删除旧的JWT(如果有的话)。为了使这些更改生效,需要更改客户端应用程序。

5 身份认证示例

 

5.1    全局启用Istio双向TLS

通过执行下面的命令启用网格范围的双向TLS身份验证策略。

$ kubectl apply -f {path/to}/meshpolicy.yaml

meshpolicy.yaml策略文件的内容如下,策略的类型为MeshPolicy,策略的名称为default。

apiVersion: “authentication.istio.io/v1alpha1”

kind: “MeshPolicy”

metadata:

name: “default”

spec:

peers:

– mtls: {}

配置客户端时,需要设置目标规则使用双向TLS。对于每一个适用的服务(或名称空间),可以使用多个目标规则。通过执行下面的命令创建目标规则:

$ kubectl apply -f {path/to}/demo-destinationrule.yaml

在istio-system命名空间下,创建一个名称为default的目标规则,流量策略mode: ISTIO_MUTUAL。

apiVersion: “networking.istio.io/v1alpha3”

kind: “DestinationRule”

metadata:

name: “default”

namespace: “istio-system”

spec:

host: “*.local”

trafficPolicy:

tls:

mode: ISTIO_MUTUAL

 

作者简介:

季向远,北京神舟航天软件技术有限公司。本文版权归原作者所有。

K8S中文社区微信公众号

评论 抢沙发

登录后评论

立即登录