智汇华云| Istio中双向TLS认证功能详解

图片[1]-智汇华云| Istio中双向TLS认证功能详解-4747i站长资讯

  一,概述

  Istio中实现了从客户端到服务器端的全互连加密功能,首先从外部的客户端发起请求,到达Istio的Ingress代理,并作为整个整个的边界网关,会再将请求转发到内部的微服务,在内部,一般会涉及到多个微服务之间的相互作用,形成一个调用链。

  在很多架构模型中,积累内部会被认为是天然安全的,微服务之间的流量也是明文传输的。这种模型现在受到越来越多的质疑,因此有些很多公有云都实现了“零信任” “网络,全互连加密的功能。

  本文会详细分析在一个内部内部,如何通过Istio实现服务之间的通信数据的加密。Istio中的加密方式是双向tls的认证,具体是指两个Envoy代理之间的首先进行双向tls认证,认证通过后将后续的数据流进行加密传输。

  例如:Pod A需要访问Pod B,在Istio中,请求都是由Envoy进行代理的,因此完整的流程是Pod A发出到Pod B的请求,然后请求会被Envoy Proxy A劫持,然后Envoy Proxy A会与Envoy代理B进行点对点的认证,认证通过后,数据会进行加密传输,请求会由Envoy代理A发送给Envoy代理B,最后再由Envoy代理B将请求转发给PodB。

图片[2]-智汇华云| Istio中双向TLS认证功能详解-4747i站长资讯

  在特使代理人A与特使代理人B之间在认证的过程中对于Pod A或者Pod B本质上都是无感知的。

  Istio中双向tls认证的基本对象是

  apiVersion:security.istio.io/v1beta1

  种类:PeerAuthentication

  二,认证配置的策略类型

  在具体进行配置的时候,有多种基本的策略

  禁用

  即一部分双向tls认证,这种情况下源Envoy与目的E​​nvoy之间没有对对方进行身份的安全确认,它们之间发送的都是明文数据

  严格

  即严格的双向tls认证模式。源Envoy与目的E​​nvoy之间必须对对方进行身份的安全确认,它们之间发送的都是加密后的数据。

  准许

  可以进行双向tls认证,也可以不进行认证从而发送明文数据。

  取消设定

  即没有进行设置,这种情况下会继承上级策略,某些当前名称空间的或者整个系统的。如果上级策略都为空,则替换设置为PERMISSIVE

  三,认证配置的范围

  Istio中对双向tls认证进行配置的时候,可以有几种不同的范围,范围越小优先级达到:

  整体

  apiVersion:security.istio.io/v1beta1

  种类:PeerAuthentication

  元数据:

  名称:默认

  命名空间:istio-system

  规格:

  mtls:

  模式:STRICT

  注意,级别的安全策略名称只能是默认值,namespace则是istio所在的系统namespace,这里是istio-system

  namespace等级,即某个namespace中所有服务

  apiVersion:security.istio.io/v1beta1

  种类:PeerAuthentication

  元数据:

  名称:默认

  命名空间:foo

  规格:

  mtls:

  模式:PERMISSIVE

  负载等级,即某个名称空间中某些特定的Pod

  apiVersion:security.istio.io/v1beta1

  种类:PeerAuthentication

  元数据:

  名称:默认

  命名空间:foo

  规格:

  选择器:

  matchLabels:

  应用:财务

  mtls:

  模式:STRICT

  突破了“ app:Finance”标签的Pod位于的使节实行STRICT模式。

  扩展等级

  apiVersion:security.istio.io/v1beta1

  种类:PeerAuthentication

  元数据:

  名称:默认

  命名空间:foo

  规格:

  选择器:

  matchLabels:

  应用:财务

  mtls:

  模式:STRICT

  portLevelMtls:

  8080:

  模式:DISABLE

  引入了“ app:finance”标签的Pod位于的Envoy实施了STRICT模式,但是插入其中的8080端口使用DISABLE模式。

  四,认证配置的具体方法

  在Istio中进行双向tls认证配置,需要注意的是客户端和服务器端配置方法是不一样的。例如在名称空间foo中有放置服务A和B,每组都有一些Pod,假设服务A的Pod这时在服务A所在的Pod中访问服务B,从而将该请求设置为STRICT模式,需要配置两处

  服务器端配置,给服务B对应的负载配置PeerAuthentication策略,这里配置的是服务B所有关联Pod对应的Envoy代理。

  apiVersion:security.istio.io/v1beta1

  种类:PeerAuthentication

  元数据:

  名称:默认

  命名空间:foo

  规格:

  选择器:

  matchLabels:

  应用程式:B

  mtls:

  模式:STRICT

  2.客户端配置,给服务B配置DestinationRule策略。这里配置的是所有访问服务B的Pod对应的Envoy代理。

  猫<< EOF | kubectl apply -n foo -f-

  apiVersion:“ networking.istio.io/v1alpha3”

  种类:“ DestinationRule”

  元数据:

  名称:“ B”

  规格:

  主机:“ B.foo.svc.cluster.local”

  trafficPolicy:

  tls:

  模式:ISTIO_MUTUAL

  紧急行动

  该客户端配置的时候需要配置目标服务的对象,而服务器端配置的时候需要配置服务器端对应负载的PeerAuthentication对象。

  五,测试case1:预设配置

  kubectl创建ns foo

  kubectl apply -f <(istioctl kube-inject -f samples / httpbin / httpbin.yaml)-n foo

  kubectl apply -f <(istioctl kube-inject -f samples / sleep / sleep.yaml)-n foo

  kubectl创建ns条

  kubectl apply -f <(istioctl kube-inject -f samples / httpbin / httpbin.yaml)-n bar

  kubectl apply -f <(istioctl kube-inject -f samples / sleep / sleep.yaml)-n bar

  kubectl创建ns遗留物

  kubectl apply -f样本/httpbin/httpbin.yaml -n旧版

  kubectl apply -f样本/sleep/sleep.yaml -n传统

  创建了3个名称空间:foo,bar和Legacy,每个名称空间分别创建了sleep和httpbin两个应用,作为客户端和服务器端。在foo和bar中的Pod有对应的Envoy Proxy,而在Legacy中则没有。下面是创造成功后的Pod情况

  [root @ master1 istio-1.6.0]#kubectl get pod –all-namespaces

  名称空间名称就绪状态重启年龄

  酒吧httpbin-67576779c-tjl4m 2/2跑步0 31m

  bar sleep-7dc44b8d45-rfhpl 2/2跑步0 31m

  foo httpbin-67576779c-tw6kl 2/2跑步0 31m

  foo sleep-7dc44b8d45-87x2p 2/2跑步0 31m

  旧版httpbin-779c54bf49-h5wrw 1/1正在运行0 31m

  旧版sleep-f8cbf5b76-b8xgd 1/1运行0 31m

  在使用默认的默认配置部署Istio的情况下,如果没有设置任何安全策略,则是PERMISSIVE,即同时允许双向tls认证和不进行任何认证的明文传输两种方式。注意这只针对有Envoy代理的情况,因为这些策略最终的执行者是Envoy,而对于那些没有Envoy Proxy的Pod,例如Legacy中的Pod,则只能使用明文方式进行收发数据。下面来验证这一点

  [root @ master1 istio-1.6.0]#for from in“ foo”“ bar”“ legacy”; 在“ foo”,“ bar”,“ legacy”中进行操作;做kubectl执行程序$(kubectl get pod -l app = sleep -n $ {from} -o jsonpath = {。items..metadata.name})-c sleep -n $ {from}-curl“ http:// httpbin。$ {to}:8000 / ip“ -s -o / dev / null -w” sleep。$ {from} to httpbin。$ {to}:%{http_code} \ n“; 完成 做完了

  sleep.foo到httpbin.foo:200

  sleep.foo到httpbin.bar:200

  sleep.foo到httpbin.legacy:200

  sleep.bar到httpbin.foo:200

  sleep.bar到httpbin.bar:200

  sleep.bar到httpbin.legacy:200

  sleep.legacy到httpbin.foo:200

  sleep.legacy到httpbin.bar:200

  sleep.legacy到httpbin.legacy:200

  可以看到任何两个睡眠与httpbin之间都是可以连通的。但是如果进一步观察,发现这些认证方式其实是不同的

  [root @ master1 istio-1.6.0]#kubectl exec $(kubectl get pod -l app = sleep -n foo -o jsonpath = {。items..metadata.name})-c sleep -n foo-curl http ://httpbin.foo:8000 / headers -s | grep X-Forwarded-Client-Cert

  “ X-Forwarded-Client-Cert”:“通过= spiffe://cluster.local/ns/foo/sa/httpbin; Hash = 41eb8aa0a91782fc1a09df8da85b586c5eaabbca3117f645cdb9df8d998b55f2; Subject = \” \“ \”; URI = spiffe:// cluster。 ns / foo / sa / sleep“

  从foo中的睡眠访问foo中的httpbin,header中带有“ X-Forwarded-Client-Cert”表明使用了双向tls认证。

  [root @ master1 istio-1.6.0]#kubectl exec $(kubectl get pod -l app = sleep -n legacy -o jsonpath = {。items..metadata.name})-c sleep -n legacy-curl http ://httpbin.foo:8000 / headers -s | grep X-Forwarded-Client-Cert

  [root @ master1 istio-1.6.0]#

  而从legacy中的睡眠访问legacy中的httpbin,header中则不会带有“ X-Forwarded-Client-Cert”,因为客户端和服务器端都没有Envoy代理,只能进行没有加密的明文传输。

  另外,还可以研磨sleep.legacy发出去的请求都是明文数据,而sleep.httpbin收到的请求也都是明文数据。而foo和bar里面的Pod发送请求时优先使用双向tls认证方式(即下面某些),这些可以自行测试验证。

  sleep.foo到httpbin.foo:200

  sleep.foo到httpbin.bar:200

  sleep.bar到httpbin.foo:200

  sleep.bar到httpbin.bar:200

  清理命令

  kubectl delete -f <(istioctl kube-inject -f samples / httpbin / httpbin.yaml)-n foo

  kubectl delete -f <(istioctl kube-inject -f samples / sleep / sleep.yaml)-n foo

  kubectl delete -f样本/httpbin/httpbin.yaml -n旧版

  kubectl delete -f样本/sleep/sleep.yaml -n旧版

  kubectl delete -f <(istioctl kube-inject -f samples / httpbin / httpbin.yaml)-n条

  kubectl delete -f <(istioctl kube-inject -f samples / sleep / sleep.yaml)-n条

  kubectl删除ns foo

  kubectl删除ns遗产

  kubectl删除ns栏

  六,测试case2:针对特定服务的配置

  首先,创建一个文本的安全策略,扩展所有的双向tls认证。

  kubectl apply -f-<< EOF

  apiVersion:“ security.istio.io/v1beta1”

  种类:“ PeerAuthentication”

  元数据:

  名称:“默认”

  命名空间:“ istio-system”

  规格:

  mtls:

  模式:DISABLE

  紧急行动

  然后创建一个foo名称空间,并在其中创建带有Envoy Proxy的sleep和httpbin

  kubectl创建ns foo

  kubectl apply -f <(istioctl kube-inject -f samples / httpbin / httpbin.yaml)-n foo

  kubectl apply -f <(istioctl kube-inject -f samples / sleep / sleep.yaml)-n foo

  这时进行测试,会发现他们之间可以正常访问,但没有使用双向tls认证,这符合预期,说明并行策略实施。

  [root @ master1 istio-1.6.0]#kubectl exec $(kubectl get pod -l app = sleep -n foo -o jsonpath = {。items..metadata.name})-c sleep -n foo-curl“ http://httpbin.foo:8000/ip“ -s -o / dev / null -w” sleep.foo到httpbin.foo:%{http_code} \ n“

  sleep.foo到httpbin.foo:200

  [root @ master1 istio-1.6.0]#kubectl exec $(kubectl get pod -l app = sleep -n foo -o jsonpath = {。items..metadata.name})-c sleep -n foo-curl http ://httpbin.foo:8000 / headers -s | grep X-Forwarded-Client-Cert

  [root @ master1 istio-1.6.0]#

  接下来为服务器端配置PeerAuthentication策略,让其强制执行双向tls认证

  猫<< EOF | kubectl apply -n foo -f-

  apiVersion:“ security.istio.io/v1beta1”

  种类:“ PeerAuthentication”

  元数据:

  名称:“ httpbin”

  命名空间:“ foo”

  规格:

  选择器:

  matchLabels:

  应用:httpbin

  mtls:

  模式:STRICT

  紧急行动

  这时再次进行测试

  [root @ master1 istio-1.6.0]#kubectl exec $(kubectl get pod -l app = sleep -n foo -o jsonpath = {。items..metadata.name})-c sleep -n foo-curl“ http://httpbin.foo:8000/ip“ -s -o / dev / null -w” sleep.foo到httpbin.foo:%{http_code} \ n“

  sleep.foo到httpbin.foo:503

  [root @ master1 istio-1.6.0]#

  出现了503错误,这实际上是一个tls冲突,因为最终当前为止我们为服务器端设置了强制使用双向tls认证,但是客户端未设置。

  接下来设置客户端。

  猫<< EOF | kubectl apply -n foo -f-

  apiVersion:“ networking.istio.io/v1alpha3”

  种类:“ DestinationRule”

  元数据:

  名称:“ httpbin”

  规格:

  主机:“ httpbin.foo.svc.cluster.local”

  trafficPolicy:

  tls:

  模式:ISTIO_MUTUAL

  紧急行动

  然后进行测试,发现现在已经可以正常访问,并且使用了双向tls认证,符合预期。

  [root @ master1 istio-1.6.0]#kubectl exec $(kubectl get pod -l app = sleep -n foo -o jsonpath = {。items..metadata.name})-c sleep -n foo-curl“ http://httpbin.foo:8000/ip“ -s -o / dev / null -w” sleep.foo到httpbin.foo:%{http_code} \ n“

  sleep.foo到httpbin.foo:200

  [root @ master1 istio-1.6.0]#kubectl exec $(kubectl get pod -l app = sleep -n foo -o jsonpath = {。items..metadata.name})-c sleep -n foo-curl http ://httpbin.foo:8000 / headers -s | grep X-Forwarded-Client-Cert

  “ X-Forwarded-Client-Cert”:“通过= spiffe://cluster.local/ns/foo/sa/httpbin; Hash = b8a73b2655b270e23eda820e49c56cc9b16521d98cb6c1896eff41c58cc32d56; Subject = \” \“; URI = spiffe:// cluster。 ns / foo / sa / sleep“

  [root @ master1 istio-1.6.0]#

  清理命令

  kubectl删除PeerAuthentication httpbin -n foo

  kubectl删除DestinationRule httpbin -n foo

  kubectl delete -f <(istioctl kube-inject -f samples / httpbin / httpbin.yaml)-n foo

  kubectl delete -f <(istioctl kube-inject -f samples / sleep / sleep.yaml)-n foo

  kubectl删除ns foo

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享