istio-双向tls

2020-07-02  本文已影响0人  与诗小睡
  1. stio 跟踪迁移到 sidecar 的服务端工作负载,并将客户端 sidecar 配置为自动向这些工作负载发送双向 TLS 流量, 同时将明文流量发送到没有 sidecar 的工作负载。这使您可以通过最少的配置,逐步在网格中使用双向 TLS。
  2. 安装 Istio 时,配置 global.mtls.enabled 选项为 false,global.mtls.auto 选项为 true。 以安装 demo 配置文件为例
[root@master bin]# istioctl manifest apply --set profile=demo \
>   --set values.global.mtls.auto=true \
>   --set values.global.mtls.enabled=false
Detected that your cluster does not support third party JWT authentication. Falling back to less secure first party JWT. See https://istio.io/docs/ops/best-practices/security/#configure-third-party-service-account-tokens for details.
! global.mtls.enabled is deprecated; use the PeerAuthentication resource instead
! global.mtls.auto is deprecated; use meshConfig.enableAutoMtls instead
✔ Istio core installed                                                                                                                                                                                                                      
✔ Istiod installed                                                                                                                                                                                                                          
✔ Egress gateways installed                                                                                                                                                                                                                 
✔ Ingress gateways installed                                                                                                                                                                                                                
✔ Addons installed                                                                                                                                                                                                                          
✔ Installation complete                                                                                                                                                                                                                     [root@master bin]# 
  1. 安装
    本例中,我们部署 httpbin 服务到 full、partial 和 legacy 三个命名空间中,分别 代表 Istio 迁移的不同阶段。命名空间 full 包含已完成 Istio 迁移的所有服务器工作负载。 每一个部署都有 Sidecar 注入
[root@master ~]# kubectl create ns full
namespace/full created
[root@master ~]# kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n full
Error: open samples/httpbin/httpbin.yaml: no such file or directory
error: no objects passed to apply
[root@master ~]# cd istio-1.6.3/
[root@master istio-1.6.3]# kubectl apply -f <(istioctl kube-inject -f samples/httpbin/httpbin.yaml) -n full
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created
[root@master istio-1.6.3]# kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n full
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created
[root@master istio-1.6.3]#

命名空间 partial 包含部分迁移到 Istio 的服务器工作负载。 只有完成迁移的服务器工作负载(由于已注入 Sidecar)能够使用双向 TLS 流量

 $ kubectl create ns partial $ kubectl apply -f <(istioctl kube-inject -f [samples/httpbin/httpbin.yaml](https://raw.githubusercontent.com/istio/istio/release-1.6/samples/httpbin/httpbin.yaml)) -n partial $ cat  <<EOF |  kubectl apply -n partial -f - apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-nosidecar spec: replicas: 1 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin version: nosidecar spec: containers: - image: docker.io/kennethreitz/httpbin imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 80 EOF

命名空间 legacy 中的工作负载,都没有注入 Sidecar。

[root@master istio-1.6.3]# kubectl create ns legacy
namespace/legacy created
[root@master istio-1.6.3]# kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
serviceaccount/httpbin created
service/httpbin created
deployment.apps/httpbin created
[root@master istio-1.6.3]# kubectl apply -f samples/sleep/sleep.yaml -n legacy
serviceaccount/sleep created
service/sleep created
deployment.apps/sleep created
[root@master istio-1.6.3]# 

您可以确认在所有命名空间部署完成。

[root@master istio-1.6.3]# kubectl get pods -n legacy
NAME                       READY   STATUS    RESTARTS   AGE
httpbin-779c54bf49-9t8wr   1/1     Running   0          5m29s
sleep-f8cbf5b76-2xfsd      1/1     Running   0          5m22s
[root@master istio-1.6.3]# kubectl get pods -n full
NAME                       READY   STATUS    RESTARTS   AGE
httpbin-56f87c9c66-9rv66   2/2     Running   0          10m
sleep-7486b7547d-nmknf     2/2     Running   0          9m49s
[root@master istio-1.6.3]# kubectl get pods -n partial
NAME                                READY   STATUS     RESTARTS   AGE
httpbin-56f87c9c66-5v8ls            0/2     Init:0/1   0          88s
httpbin-nosidecar-cc684fdb4-nqp8d   1/1     Running    0          7m45s
[root@master istio-1.6.3]#

您还需验证系统中是否存在默认的网格验证策略,可以参考下面操作:

[root@master istio-1.6.3]# kubectl get policies.authentication.istio.io --all-namespaces
error: the server doesn't have a resource type "policies"
[root@master istio-1.6.3]# kubectl get meshpolicies -o yaml | grep ' mode'
error: the server doesn't have a resource type "meshpolicies"
[root@master istio-1.6.3]# 

最后但并非最不重要的一点是,确认没有应用于示例服务的目标规则。 您可以通过检查已有目标规则的 host: 字段,并确保它们没有匹配我们的示例服务。例如:

[root@master istio-1.6.3]# kubectl get destinationrules.networking.istio.io --all-namespaces -o yaml | grep "host:"
[root@master istio-1.6.3]# 

您可通过使用 curl 从命名空间 full、partial 或 legacy 中的任一 sleep Pod 发送 HTTP 请求到 httpbin.full、httpbin.partial 或 httpbin.legacy 以验证安装。 所有的请求都应成功返回 HTTP 200 状态码。
例如,这是一个检查 sleep.full 到 httpbin.full 可达性的命令

[root@master istio-1.6.3]# kubectl exec $(kubectl get pod -l app=sleep -n full -o jsonpath={.items..metadata.name}) -c sleep -n full -- curl http://httpbin.full:8000/headers  -s  -w "response %{http_code}\n" | egrep -o 'URI\=spiffe.*sa/[a-z]*|response.*$'
URI=spiffe://cluster.local/ns/full/sa/sleep
response 200
[root@master istio-1.6.3]#

SPIFFE URI 显示来自 X509 证书的客户端标识,它表明流量是在双向 TLS 中发送的。 如果流量为明文,将不会显示客户端证书。

[root@master istio-1.6.3]# kubectl  get namespaces
NAME              STATUS   AGE
default           Active   5d22h
full              Active   17m
heptio-contour    Active   5d17h
istio-system      Active   5d17h
kube-node-lease   Active   5d22h
kube-public       Active   5d22h
kube-system       Active   5d22h
legacy            Active   12m
partial           Active   14m
[root@master istio-1.6.3]# kubectl  get pods -n full
NAME                       READY   STATUS    RESTARTS   AGE
httpbin-56f87c9c66-9rv66   2/2     Running   0          16m
sleep-7486b7547d-nmknf     2/2     Running   0          16m
[root@master istio-1.6.3]# kubectl  exec  -it sleep-7486b7547d-nmknf -c sleep -- curl http://httpbin.full:8000/headers
Error from server (NotFound): pods "sleep-7486b7547d-nmknf" not found
[root@master istio-1.6.3]# kubectl  exec  -it sleep-7486b7547d-nmknf   -n full  -c sleep -- curl http://httpbin.full:8000/headers
{
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "0", 
    "Host": "httpbin.full:8000", 
    "User-Agent": "curl/7.69.1", 
    "X-B3-Parentspanid": "971df015905548b4", 
    "X-B3-Sampled": "1", 
    "X-B3-Spanid": "df4cc5e1187fb09f", 
    "X-B3-Traceid": "42951d2c32eb240e971df015905548b4", 
    "X-Envoy-Attempt-Count": "1", 
    "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/full/sa/httpbin;Hash=9302b39c8b2077e5933cfed8f17d8e86b2a503880a04068126517f4edfe01aaf;Subject=\"\";URI=spiffe://cluster.local/ns/full/sa/sleep"
  }
}
[root@master istio-1.6.3]# kubectl  exec  -it sleep-7486b7547d-nmknf   -n full  -c sleep -- curl http://httpbin.legacy:8000/headers
{
  "headers": {
    "Accept": "*/*", 
    "Content-Length": "0", 
    "Host": "httpbin.legacy:8000", 
    "User-Agent": "curl/7.69.1", 
    "X-B3-Sampled": "1", 
    "X-B3-Spanid": "f78d3c023364cb2c", 
    "X-B3-Traceid": "3ea979fb1c0a73faf78d3c023364cb2c", 
    "X-Envoy-Attempt-Count": "1", 
    "X-Envoy-Decorator-Operation": "httpbin.legacy.svc.cluster.local:8000/*", 
    "X-Envoy-Peer-Metadata": "ChoKCkNMVVNURVJfSUQSDBoKS3ViZXJuZXRlcwoeCgxJTlNUQU5DRV9JUFMSDhoMMTAwLjEyMi4yNS45CnkKBkxBQkVMUxJvKm0KDgoDYXBwEgcaBXNsZWVwChIKDGlzdGlvLmlvL3JldhICGgAKIQoRcG9kLXRlbXBsYXRlLWhhc2gSDBoKNzQ4NmI3NTQ3ZAokChlzZWN1cml0eS5pc3Rpby5pby90bHNNb2RlEgcaBWlzdGlvChoKB01FU0hfSUQSDxoNY2x1c3Rlci5sb2NhbAogCgROQU1FEhgaFnNsZWVwLTc0ODZiNzU0N2Qtbm1rbmYKEwoJTkFNRVNQQUNFEgYaBGZ1bGwKSQoFT1dORVISQBo+a3ViZXJuZXRlczovL2FwaXMvYXBwcy92MS9uYW1lc3BhY2VzL2RlZmF1bHQvZGVwbG95bWVudHMvc2xlZXAKGgoPU0VSVklDRV9BQ0NPVU5UEgcaBXNsZWVwChgKDVdPUktMT0FEX05BTUUSBxoFc2xlZXA=", 
    "X-Envoy-Peer-Metadata-Id": "sidecar~100.122.25.9~sleep-7486b7547d-nmknf.full~full.svc.cluster.local"
  }
}
[root@master istio-1.6.3]# 

SPIFFE URI 显示来自 X509 证书的客户端标识,它表明流量是在双向 TLS 中发送的。 如果流量为明文,将不会显示客户端证书

PERMISSIVE 模式
这里,我们从开启网格服务双向 TLS 的 PERMISSIVE 模式开始

  1. 所有的 httpbin.full 工作负载以及在 httpbin.partial 中使用了 Sidecar 的工作负载都能够使用双向 TLS 和明文流量。
  2. 命名空间 httpbin.partial 中没有 Sidecar 的服务和 httpbin.legacy 中的服务都只能使用明文流量。
    自动双向 TLS 将客户端和 sleep.full 配置为可将双向 TLS 流量发送到具有 Sidecar 的工作负载,明文流量发送到没有 Sidecar 的工作负载。
[root@master istio-1.6.3]# for from in "full" "legacy"; do for to in "full" "partial" "legacy"; do echo "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}\n" | egrep -o 'URI\=spiffe.*sa/[a-z]*|response.*$';  echo -n "\n"; done; done
sleep.full to httpbin.full
URI=spiffe://cluster.local/ns/full/sa/sleep
response code: 200
\nsleep.full to httpbin.partial
URI=spiffe://cluster.local/ns/full/sa/sleep
response code: 200
\nsleep.full to httpbin.legacy
response code: 200
\nsleep.legacy to httpbin.full
response code: 200
\nsleep.legacy to httpbin.partial
response code: 200
\nsleep.legacy to httpbin.legacy
response code: 200
\n[root@master istio-1.6.3]# 

使用 Sidecar 迁移:
无论工作负载是否带有 Sidecar,对 httpbin.partial 的请求都可以到达。 Istio 自动将 sleep.full 客户端配置为使用双向 TLS 连接带有 Sidecar 的工作负载。

[root@master istio-1.6.3]# for i in `seq 1 10`; do kubectl exec $(kubectl get pod -l app=sleep -n full -o jsonpath={.items..metadata.name}) -c sleep -nfull  -- curl http://httpbin.partial:8000/headers  -s  -w "response code: %{http_code}\n" | egrep -o 'URI\=spiffe.*sa/[a-z]*|response.*$';  echo -n "\n"; done
URI=spiffe://cluster.local/ns/full/sa/sleep
response code: 200
\nresponse code: 200
\nURI=spiffe://cluster.local/ns/full/sa/sleep
response code: 200
\nresponse code: 200
\nresponse code: 200
\nURI=spiffe://cluster.local/ns/full/sa/sleep
response code: 200
\nresponse code: 200
\nURI=spiffe://cluster.local/ns/full/sa/sleep
response code: 200
\nresponse code: 200
\nURI=spiffe://cluster.local/ns/full/sa/sleep
response code: 200
\n[root@master istio-1.6.3]# 

如果不使用自动双向 TLS,您必须跟踪 Sidecar 迁移完成情况,然后显式的配置目标规则,使客户端发送双向 TLS 流量到 httpbin.full。

锁定双向 TLS 为 STRICT 模式

您可配置认证策略为 STRICT,以锁定 httpbin.full 服务仅接收双向 TLS 流量

[root@master istio-1.6.3]#  kubectl apply -n full -f - <<EOF
> apiVersion: "security.istio.io/v1beta1"
> kind: "PeerAuthentication"
> metadata:
>   name: "default"
> spec:
>   mtls:
>     mode: STRICT
> EOF
peerauthentication.security.istio.io/default created
[root@master istio-1.6.3]# 

测试:

[root@master istio-1.6.3]# kubectl  exec -it sleep-f8cbf5b76-2xfsd -n legacy -- curl http://httpbin.full:8000   
curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56
[root@master istio-1.6.3]# 

现在来自 sleep.legacy 的请求将开始失败,因为其不支持发送双向 TLS 流量。 但是客户端 sleep.full 的请求将仍可成功返回 200 状态码,因为它已配置为自动双向 TLS,并且发送双向 TLS 请求。

整个服务网格全部限定为双向tls 流量:

kubectl apply -n istio-system -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
  name: "default"
spec:
  mtls:
    mode: STRICT
EOF

清理:

[root@master istio-1.6.3]# kubectl delete ns full partial legacy    
namespace "full" deleted
namespace "partial" deleted
namespace "legacy" deleted
上一篇 下一篇

猜你喜欢

热点阅读