Istio提供双向TLS作为服务到服务身份验证的解决方案。

双向认证是指单方同时进行认证,这是某些协定的默认认证形式。以前称为“互相实体认证” ,因为两个或多个实体在传输任何数据或信息之前会验证对方的合法性。

上面是istio服务之间mTLS流:

  1. 客户端应用程序容器将纯文本HTTP申请发送到服务器。
  2. 客户端代理容器拦挡出站申请。
  3. 客户端代理与服务器端代理执行TLS握手。此握手包含证书替换。这些证书由Istio预加载到代理容器中。
  4. 客户端代理对服务器的证书执行平安命名查看,以验证受权身份正在运行服务器。
  5. 客户端和服务器建设互相TLS连贯,服务器代理将申请转发到服务器应用程序容器。

实现细节

从Istio 1.5开始,Istio应用主动双向TLS。这意味着,只管服务同时承受纯文本和TLS通信,但默认状况下,服务将在集群内发送TLS申请。

与其余Istio配置一样,您能够在.yaml文件中指定身份验证策略。您应用kubectl部署策略。以下示例身份验证策略指定带有app: reviews标签的工作负载的传输身份验证必须应用双向TLS:

apiVersion: "security.istio.io/v1beta1"kind: "PeerAuthentication"metadata:  name: "example-peer-policy"  namespace: "foo"spec:  selector:    matchLabels:      app: reviews  mtls:    mode: STRICT

作用域

在Istio中,能够通过三个粒度级别定义mTLS设置。对于每种服务,Istio都会利用最窄的匹配策略。程序为:服务特定,命名空间范畴,网格范畴。

  • 网格范畴:为根名称空间指定的策略,不带有或带有空的选择器字段。
  • 命名空间范畴:为没有或没有空选择器字段的非根名称空间指定的策略。
  • 服务特定:在惯例名称空间中定义的策略,带有非空选择器字段。

例如咱们下面的示例就是一个服务特定的策略。

每个命名空间只能有一个网格范畴的对等身份验证策略,并且只能有一个命名空间范畴的对等身份验证策略。当您为同一网格或名称空间配置多个网格范畴或命名空间范畴的对等身份验证策略时,Istio会疏忽较新的策略。当多个特定于工作负载的对等身份验证策略匹配时,Istio将抉择最旧的策略。

模式

对等身份验证策略指定Istio对指标工作负载施行的双向TLS模式。反对以下模式:

  • PERMISSIVE:工作负载承受双向TLS和纯文本流量。当没有Sidecar的工作负载无奈应用双向TLS时,此模式在迁徙过程中最有用。通过应用sidecar注入迁徙工作负载后,您应该将模式切换为STRICT
  • STRICT:工作负载仅承受双向TLS通信。、
  • DISABLE:互相TLS已禁用。从平安角度来看,除非您提供本人的平安解决方案,否则不应应用此模式。

勾销设置模式时,将继承父作用域的模式。缺省状况下,未设置模式的网格范畴对等身份验证策略应用PERMISSIVE模式。

此时,您能够在Istio中将任何服务设置为任何mTLS模式。然而,让咱们看一下In mesh(从网格内)或out of mesh(网分外)调用服务时每种模式会产生什么状况?

In mesh 示意Sidecar代理在应用程序容器旁边运行。Out of mesh意味着没有Sidecar容器。

总结的表格如下:

  • PERMISSIVE 在网格内应用mTLS,在网分外应用纯文本连贯
  • STRICT 在网格内应用mTLS,但回绝来自网分外的连贯
  • DISABLED 在网格内外都应用纯文本连贯

Demo

该demo,咱们会创立两个服务,别离查看未启用和启用对等身份验证策略的服务拜访状况。

首先部署demo中须要的资源等:

kubectl create ns fookubectl label namespace foo istio-injection=enabledkubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/httpbin/httpbin.yaml -n fookubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/sleep/sleep.yaml -n foo

sleep 应用程序是咱们本次demo的客户端。httpbin 应用程序是咱们本次demo的服务端。

咱们查看一下拜访状况,exec 到 sleep pod,而后对 httpbin pod 执行 curl:

curl http://httpbin:8000<!DOCTYPE html><html lang="en">......

拜访胜利。正如后面讲到的,istio1.5 之后主动mtls。在未设置非凡对等策略下,是能够承受纯文本申请。

接下来咱们设置一个命名空间级别的对等策略,并且模式为严格:

apiVersion: security.istio.io/v1beta1kind: PeerAuthenticationmetadata:  name: default  namespace: foospec:  mtls:    mode: STRICT

容许名称空间foo下所有工作负载的mTLS通信。

应用kubectl 将该策略利用到集群。

kubectl apply -f policy.yamlpeerauthentication.security.istio.io/default created

接着咱们再次进入到sleep pod,对 httpbin pod 执行 curl:

curl http://httpbin:8000<!DOCTYPE html><html lang="en">......

拜访仍旧能够胜利,这不是阐明了咱们对等策略没有失效。因为sleep 程序在mesh当中。

接下来,咱们部署一个没有sidecar的sleep程序,即咱们检测mesh外利用拜访状况,咱们另外创立了一个命名空间legacy,并且没有对其作istio-injection=enabled 标签解决,从而通知istio疏忽该命名空间利用。

kubectl create ns legacykubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/sleep/sleep.yaml -n legacy

咱们进入到legacy命名空间下的sleep pod,对 httpbin pod 执行 curl:

curl http://httpbin.foo:8000curl: (56) Recv failure: Connection reset by peer

拜访失败。因为咱们对foo命名设置了严格模式的mTLS策略。纯文本申请将不被容许,因为身份验证失败。

当然咱们此时能够删除创立的严格对等策略,之后拜访恢复正常。