本文使用istio版本为v1.9.2。
Istio安全架构图如下:
从图中可知安全方面主要集中在以下几个方面:
-
终端用户基于JWT的身份认证方案;
-
经网关(ingress/egress)的流量安全;
-
网格内部的流量安全(认证,授权);
-
Istio自身的安全方案;
一、 网格内部流量
1. 自动双向TLS
除非显示的指定,否则通过官方的配置(default/demo等)安装的istio,均默认开启了双向TLS认证(mtls, mutual TLS),正如"Istio安全架构图"中展示的,网格内服务间通信时双方的envoy代理数据是被TLS加密的。
源码部分可参考github,默认mTLS配置被置为true
:
EnableAutoMtls: &types.BoolValue{Value: true},
具体配置可参考官网释义。
老版本通过
Values.global.mtls.enabled
和Values.global.mtls.auto
来配置,新版本替换为'PeerAuthentication
和meshConfig.enableAutoMtls
,参见github。
默认情况下istio使用自生成的证书与密钥等进行mTLS加密,并根据认证等策略异步发送配置到目标端点。代理收到配置后,新的认证要求会立即生效。
a. 实例验证
分别创建full
,part
,legacy
三个命名空间,分别部署httpbin
与sleep
服务,除了legacy
之外其他均注入边车。
# kubectl create ns full
# kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n full
# kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n full
# kubectl create ns part
# kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n part
# kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n part
# kubectl create ns legacy
# kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
# kubectl apply -f samples/sleep/sleep.yaml -n legacy
若流量被istio双向TLS加密,则代理自动在消息头中添加了X-Forwarded-Client-Cer
,可通过httpbin
服务的/headers
查看。
# kubectl -nfull exec -it deploy/sleep -- curl -s http://httpbin.part:8000/headers | grep X-Forwarded-Client-Cert
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/full/sa/httpbin;Hash=aa013048768c74c5289c2ae4bbab4f944cb878d13e7dee78aa75d7b7930a34fc;Subject=\"\";URI=spiffe://cluster.local/ns/full/sa/sleep"
通过以下循环,使得三个命名空间下的服务进行互相访问测试,均能正常访问:
# for from in "full" "part" "legacy"; do for to in "full" "part" "legacy"; do echo -e "sleep.${from} to httpbin.${to}";kubectl exec "$(kubectl get pod -l app=sleep -n ${from} -o jsonpath={.items..metadata.name})" -c sleep -n ${from} -- curl "http://httpbin.${to}:8000/headers" -s -w "response code: %{http_code}" | egrep -o 'URI\=spiffe.*sa/[a-z]*|response.*$';echo ; done; done
sleep.full to httpbin.full
URI=spiffe://cluster.local/ns/full/sa/sleep # 双向mTLS
response code: 200
sleep.full to httpbin.part
URI=spiffe://cluster.local/ns/full/sa/sleep # 双向mTLS
response code: 200
sleep.full to httpbin.legacy # 宽容模式,明文
response code: 200
sleep.part to httpbin.full
URI=spiffe://cluster.local/ns/part/sa/sleep # 双向mTLS
response code: 200
sleep.part to httpbin.part
URI=spiffe://cluster.local/ns/part/sa/sleep # 双向mTLS
response code: 200
sleep.part to httpbin.legacy # 宽容模式,明文
response code: 200
sleep.legacy to httpbin.full # 宽容模式,明文
response code: 200
sleep.legacy to httpbin.part # 宽容模式,明文
response code: 200
sleep.legacy to httpbin.legacy # 宽容模式,明文
response code: 200
从测试结果来看,只有互相具备代理容器的服务相互访问才被添加了mTLS,其他情况下流量均为被加密。
这是istio具备的一种特殊模式:宽容模式(permissive mode)。
2. 同级认证策略
宽容模式也是在双向TLS中默认开启的,允许网格内服务同时接受纯文本流量和双向 TLS 流量,由代理自动识别并决定是否加密(两个http服务都携带边车,两者边车默认mTLS通信;当其中