Istio 提供双向 TLS 作为服务到服务身份验证的解决方案。
双向认证是指单方同时进行认证,这是某些协定的默认认证形式。以前称为“互相实体认证”,因为两个或多个实体在传输任何数据或信息之前会验证对方的合法性。
上面是 istio 服务之间 mTLS 流:
- 客户端应用程序容器将纯文本 HTTP 申请发送到服务器。
- 客户端代理容器拦挡出站申请。
- 客户端代理与服务器端代理执行 TLS 握手。此握手包含证书替换。这些证书由 Istio 预加载到代理容器中。
- 客户端代理对服务器的证书执行平安命名查看,以验证受权身份正在运行服务器。
- 客户端和服务器建设互相 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 foo
kubectl label namespace foo istio-injection=enabled
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/httpbin/httpbin.yaml -n foo
kubectl 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/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: foo
spec:
mtls:
mode: STRICT
容许名称空间 foo 下所有工作负载的 mTLS 通信。
应用 kubectl 将该策略利用到集群。
kubectl apply -f policy.yaml
peerauthentication.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 legacy
kubectl 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:8000
curl: (56) Recv failure: Connection reset by peer
拜访失败。因为咱们对 foo 命名设置了严格模式的 mTLS 策略。纯文本申请将不被容许,因为身份验证失败。
当然咱们此时能够删除创立的严格对等策略,之后拜访恢复正常。