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


metadata:
name: "B"
spec:
host: "B.foo.svc.cluster.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
EOF
也就是说客户端配置的时候需要配置目的服务的DestinationRule对象 , 而服务器端配置的时候需要配置服务器端对应负载的PeerAuthentication对象 。
五、测试case1:默认配置
kubectl create ns foo
kubectl apply -f
kubectl apply -f
kubectl create ns bar
kubectl apply -f
kubectl apply -f
kubectl create ns legacy
kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
kubectl apply -f samples/sleep/sleep.yaml -n legacy
创建了3个namespace:foo, bar和legacy , 每个namespace分别创建了sleep和httpbin两种应用 , 作为客户端和服务器端 。 在foo和bar中的Pod有对应的Envoy Proxy , 而在legacy中则没有 。 下面是创建成功后的Pod情况
[root@master1 istio-1.6.0]# kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
bar httpbin-67576779c-tjl4m 2/2 Running 0 31m
bar sleep-7dc44b8d45-rfhpl 2/2 Running 0 31m
foo httpbin-67576779c-tw6kl 2/2 Running 0 31m
foo sleep-7dc44b8d45-87x2p 2/2 Running 0 31m
legacy httpbin-779c54bf49-h5wrw 1/1 Running 0 31m
legacy sleep-f8cbf5b76-b8xgd 1/1 Running 0 31m
在使用默认的default配置部署Istio的情况下 , 如果没有设置任何安全策略 , 默认是PERMISSIVE , 即同时允许双向tls认证和不进行任何认证的明文传输两种方式 。 注意这只针对有Envoy Proxy的情况 , 因为这些策略最终的执行者是Envoy , 而对于那些没有Envoy Proxy的Pod , 例如legacy中的Pod , 则只能使用明文方式进行收发数据 。 下面来验证这一点
[root@master1 istio-1.6.0]# for from in "foo" "bar" "legacy"; do for to in "foo" "bar" "legacy"; do kubectl exec $(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"; done; done
sleep.foo to httpbin.foo: 200
sleep.foo to httpbin.bar: 200
sleep.foo to httpbin.legacy: 200
sleep.bar to httpbin.foo: 200
sleep.bar to httpbin.bar: 200
sleep.bar to httpbin.legacy: 200
sleep.legacy to httpbin.foo: 200
sleep.legacy to httpbin.bar: 200
sleep.legacy to httpbin.legacy: 200
可以看到任何两个sleep与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-s | grep X-Forwarded-Client-Cert
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/foo/sa/httpbin;Hash=41eb8aa0a91782fc1a09df8da85b586c5eaabbca3117f645cdb9df8d998b55f2;Subject=\"\";URI=spiffe://cluster.local/ns/foo/sa/sleep"
从foo中的sleep访问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-s | grep X-Forwarded-Client-Cert
[root@master1 istio-1.6.0]#
而从legacy中的sleep访问legacy中的httpbin , header中则不会带有"X-Forwarded-Client-Cert" , 因为客户端和服务器端都没有Envoy Proxy , 只能进行没有任何加密的明文传输 。
另外 , 还可以看出sleep.legacy发出去的请求都是明文数据 , 而sleep.httpbin收到的请求也都是明文数据 。 而foo和bar里面的Pod发送请求时则会优先使用双向tls认证方式(即下面四种) , 这些可以自行测试验证 。
sleep.foo to httpbin.foo: 200
sleep.foo to httpbin.bar: 200
sleep.bar to httpbin.foo: 200
sleep.bar to httpbin.bar: 200
清理命令
kubectl delete -f
kubectl delete -f
kubectl delete -f samples/httpbin/httpbin.yaml -n legacy
kubectl delete -f samples/sleep/sleep.yaml -n legacy
kubectl delete -f
kubectl delete -f
kubectl delete ns foo
kubectl delete ns legacy
kubectl delete ns bar
六、测试case2:针对特定服务的配置
首先 , 创建一个全局的安全策略 , 禁用所有的双向tls认证 。
kubectl apply -f -
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
name: "default"
namespace: "istio-system"
spec:
mtls:
mode: DISABLE
EOF
然后创建一个foo namespace , 并在其中创建带有Envoy Proxy的sleep和httpbin
kubectl create ns foo
kubectl apply -f
kubectl apply -f
这时进行测试 , 会发现他们之间可以正常访问 , 但没有使用双向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 "" -s -o /dev/null -w "sleep.foo to httpbin.foo: %{http_code}\n"