Peer Authentication Policy使用要点测试案例

准备基础环境

01-demoapp-v10

[root@k8s-master ms-demo]# cat 01-demoapp-v10/deploy-demoapp.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: demoappv10
    version: v1.0
  name: demoappv10
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  selector:
    matchLabels:
      app: demoapp
      version: v1.0
  template:
    metadata:
      labels:
        app: demoapp
        version: v1.0
    spec:
      containers:
      - image: ikubernetes/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        name: demoapp
        env:
        - name: "PORT"
          value: "8080"
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        resources:
          limits:
            cpu: 50m
---
apiVersion: v1
kind: Service
metadata:
  name: demoappv10
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: demoapp
    version: v1.0
  type: ClusterIP
---
   
[root@k8s-master ms-demo]# cat 01-demoapp-v10/deploy-proxy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: proxy
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: proxy
  template:
    metadata:
      labels:
        app: proxy
    spec:
      containers:
        - env:
          - name: PROXYURL
            value: http://demoappv10:8080
          image: ikubernetes/proxy:v0.1.1
          imagePullPolicy: IfNotPresent
          name: proxy
          ports:
            - containerPort: 8080
              name: web
              protocol: TCP
          resources:
            limits:
              cpu: 50m
---
apiVersion: v1
kind: Service
metadata:
  name: proxy
spec:
  ports:
    - name: http-80
      port: 80
      protocol: TCP
      targetPort: 8080
  selector:
    app: proxy
---

02-demoapp-v11

[root@k8s-master ms-demo]# cat 02-demoapp-v11/deploy-demoapp-v11.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: demoappv11
    version: v1.1
  name: demoappv11
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  selector:
    matchLabels:
      app: demoapp
      version: v1.1
  template:
    metadata:
      labels:
        app: demoapp
        version: v1.1
    spec:
      containers:
      - image: ikubernetes/demoapp:v1.1
        imagePullPolicy: IfNotPresent
        name: demoapp
        env:
        - name: "PORT"
          value: "8080"
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        resources:
          limits:
            cpu: 50m
---
apiVersion: v1
kind: Service
metadata:
  name: demoappv11
spec:
  ports:
    - name: http-8080
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: demoapp
    version: v1.1
  type: ClusterIP
---
[root@k8s-master ms-demo]# cat 02-demoapp-v11/service-demoapp.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: demoapp
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: demoapp
  type: ClusterIP
---
[root@k8s-master ms-demo]# cat 02-demoapp-v11/deploy-proxy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: proxy
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: proxy
  template:
    metadata:
      labels:
        app: proxy
    spec:
      containers:
        - env:
          - name: PROXYURL
            value: http://demoapp:8080
          image: ikubernetes/proxy:v0.1.1
          imagePullPolicy: IfNotPresent
          name: proxy
          ports:
            - containerPort: 8080
              name: web
              protocol: TCP
          resources:
            limits:
              cpu: 50m
---
apiVersion: v1
kind: Service
metadata:
  name: proxy
spec:
  ports:
    - name: http-80
      port: 80
      protocol: TCP
      targetPort: 8080
  selector:
    app: proxy
---
[root@k8s-master ms-demo]# cat 02-demoapp-v11/virutalservice-demoapp.yaml 
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - uri:
        prefix: /canary
    rewrite:
      uri: /
    route:
    - destination:
        host: demoappv11
  - name: default
    route:
    - destination:
        host: demoappv10

03-demoapp-subset

[root@k8s-master ms-demo]# cat 03-demoapp-subset/destinationrule-demoapp.yaml 
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  subsets:
  - name: v10
    labels:
      version: v1.0
  - name: v11
    labels:
      version: v1.1
[root@k8s-master ms-demo]# cat 03-demoapp-subset/virutalservice-demoapp.yaml 
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - uri:
        prefix: /canary
    rewrite:
      uri: /
    route:
    - destination:
        host: demoapp
        subset: v11
  - name: default
    route:
    - destination:
        host: demoapp
        subset: v10

04-proxy-gateway

[root@k8s-master ms-demo]# cat 04-proxy-gateway/gateway-proxy.yaml 
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: proxy-gateway
  namespace: istio-system        # 要指定为ingress gateway pod所在名称空间
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "fe.yzy.com"
[root@k8s-master ms-demo]# cat 04-proxy-gateway/virtualservice-proxy.yaml 
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: proxy
spec:
  hosts:
  - "fe.yzy.com"                     # 对应于gateways/proxy-gateway
  gateways:
  - istio-system/proxy-gateway       # 相关定义仅应用于Ingress Gateway上
  #- mesh
  http:
  - name: default
    route:
    - destination:
        host: proxy
kubectl apply -f ./01-demoapp-v10 
kubectl apply -f ./02-demoapp-v11
kubectl apply -f ./03-demoapp-subset
kubectl delete svc demoappv10 demoappv11 
kubectl apply -f ./04-proxy-gateway

 创建PA,模式为PERMISSIVE

[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl apply -f 01-namespace-default-peerauthn.yaml 
[root@k8s-master 01-PeerAuthentication-Policy-Basics]# cat 01-namespace-default-peerauthn.yaml 
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: PERMISSIVE
---
[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl get pa
NAME      MODE         AGE
default   PERMISSIVE   3s
[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl apply -f /root/istio-1.14.1/samples/sleep/sleep.yaml

 看下sleep在哪个node上,然后去该node进行tcp抓包,我的是在node2上

[root@k8s-master sleep]# kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
demoappv10-b5d9576cc-54jxx    2/2     Running   0          51m   10.244.36.90     k8s-node1   <none>           <none>
demoappv10-b5d9576cc-5hx8d    2/2     Running   0          51m   10.244.169.148   k8s-node2   <none>           <none>
demoappv10-b5d9576cc-f6fpb    2/2     Running   0          51m   10.244.169.154   k8s-node2   <none>           <none>
demoappv11-77755cdc65-2xz4d   2/2     Running   0          50m   10.244.36.78     k8s-node1   <none>           <none>
demoappv11-77755cdc65-6prmq   2/2     Running   0          50m   10.244.169.145   k8s-node2   <none>           <none>
proxy-7f9c9ffff5-2kcd6        2/2     Running   0          50m   10.244.169.156   k8s-node2   <none>           <none>
sleep-698cfc4445-p84t6        2/2     Running   0          17m   10.244.169.151   k8s-node2   <none>           <none>

sleep的ip是10.244.169.151匹配的接口是cali52787c1ffa8

[root@k8s-node2 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.211.55.1     0.0.0.0         UG    100    0        0 eth0
10.211.55.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0
10.244.36.64    10.211.55.21    255.255.255.192 UG    0      0        0 tunl0
10.244.169.128  0.0.0.0         255.255.255.192 U     0      0        0 *
10.244.169.145  0.0.0.0         255.255.255.255 UH    0      0        0 califb18e2b98c0
10.244.169.148  0.0.0.0         255.255.255.255 UH    0      0        0 calia109ade752f
10.244.169.151  0.0.0.0         255.255.255.255 UH    0      0        0 cali52787c1ffa8
10.244.169.154  0.0.0.0         255.255.255.255 UH    0      0        0 cali4a7d42ee79a
10.244.169.156  0.0.0.0         255.255.255.255 UH    0      0        0 cali214f50b2299
10.244.235.192  10.211.55.20    255.255.255.192 UG    0      0        0 tunl0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0

直接抓cali52787c1ffa8接口8080端口

[root@k8s-node2 ~]# tcpdump -i cali52787c1ffa8 -nn -X tcp port 8080

[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl exec -it sleep-698cfc4445-p84t6 -- /bin/sh
/ $ curl demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-b5d9576cc-5hx8d, ServerIP: 10.244.169.148!
/ $ curl demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-b5d9576cc-f6fpb, ServerIP: 10.244.169.154!

 查看抓包结果内容是加密的,就可以证明如果客户端和服务端都支持双向TLS通信,双方建立的就是双向TLS通信。

在demo namespace下创建一个pods,查看一下client运行的node节点

[root@k8s-master ~]# kubectl create ns demo
[root@k8s-master ~]# kubectl run client-$RANDOM --image=ikubernetes/admin-box:v1.2 -it --restart=Never -n demo --command -- /bin/sh
root@client-10058 # curl demoapp.default:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-b5d9576cc-f6fpb, ServerIP: 10.244.169.154!

[root@k8s-master sleep]# kubectl get pods -o wide -n demo
NAME           READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
client-10058   1/1     Running   0          4m22s   10.244.169.157   k8s-node2   <none>           <none>

用client再次访问demoapp.default:8080,然后抓包

[root@k8s-node2 ~]# tcpdump -i cali79b091049f0 -nn -X tcp port 8080

可以看到这个抓包结果是明文的,已经可以看到HTTP的一些访问信息

通过上面的实验就证明如果服务端定义的策略是PERMISSIVE,只要客户端无论支持不支持都能与服务端进行通信,如果支持建立起来的就是mTLS通信,如果不支持就是明文通信。

 

创建一个mode为STRICT模式的PA

[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl apply -f 02-demoapp-peerauthn.yaml 
[root@k8s-master 01-PeerAuthentication-Policy-Basics]# cat 02-demoapp-peerauthn.yaml 
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: demoapp
  namespace: default
spec:
  selector:
    matchLabels:
      app: demoapp
  mtls:
    mode: STRICT
---

在sleep上curl访问

[root@k8s-master ~]# kubectl exec -it sleep-698cfc4445-p84t6 -- /bin/sh
/ $ 
/ $ curl demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-b5d9576cc-5hx8d, ServerIP: 10.244.169.148!
/ $ curl demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-b5d9576cc-f6fpb, ServerIP: 10.244.169.154!
/ $ 

抓包结果可以看出也还是加密的 

使用client访问demoapp,可以看到是拒绝的

原因是因为服务端必须要求建立TLS通信,而客户端不支持,所以会被拒绝掉

[root@k8s-master ~]# kubectl run client-$RANDOM --image=ikubernetes/admin-box:v1.2 -it --restart=Never -n demo --command -- /bin/sh
root@client-10058 # curl demoapp.default:8080
curl: (56) Recv failure: Connection reset by peer

 

客户端禁止使用TLS通信

[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl apply -f 03-destinationrule-demoapp-mtls.yaml 
destinationrule.networking.istio.io/demoapp configured 
[root@k8s-master 01-PeerAuthentication-Policy-Basics]# cat 03-destinationrule-demoapp-mtls.yaml 
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    tls:
      mode: DISABLE
  subsets:
  - name: v10
    labels:
      version: v1.0
  - name: v11
    labels:
      version: v1.1

继续用sleep访问demoapp

/ $ curl demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-b5d9576cc-f6fpb, ServerIP: 10.244.169.154!
/ $ 

查看抓包结果

tcpdump -icali52787c1ffa8 -nn -X tcp port 8080

 

创建客户端要求通信必须为TLS

[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl apply -f 03-destinationrule-demoapp-mtls.yaml 
destinationrule.networking.istio.io/demoapp configured
[root@k8s-master 01-PeerAuthentication-Policy-Basics]# cat 03-destinationrule-demoapp-mtls.yaml 
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v10
    labels:
      version: v1.0
  - name: v11
    labels:
      version: v1.1
/ $ curl demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-b5d9576cc-54jxx, ServerIP: 10.244.36.90!
/ $ 

 将服务端TLS加密关掉

[root@k8s-master 01-PeerAuthentication-Policy-Basics]# kubectl apply -f 01-namespace-default-peerauthn.yaml 
[root@k8s-master 01-PeerAuthentication-Policy-Basics]# cat 01-namespace-default-peerauthn.yaml 
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: DISABLE
---

使用客户端访问,可以看到是访问失败的。

是因为客户端必须要求加密,服务不支持加密

修改为PERMISSIVE又可以继续通信了

[root@k8s-master 01-PeerAuthentication-Policy-Basics]# cat 01-namespace-default-peerauthn.yaml 
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: default
spec:
  mtls:
    mode: PERMISSIVE
---

将模式改为SIMPLE

[root@master 01-PeerAuthentication-Policy-Basics]# cat 03-destinationrule-demoapp-mtls.yaml 
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    tls:
      mode: SIMPLE
  subsets:
  - name: v10
    labels:
      version: v1.0
  - name: v11
    labels:
      version: v1.1

再次访问发现被拒绝掉了,是因为SIMPLE模式不会使用Istio发过来的证书

posted @ 2022-09-20 14:06  Maniana  阅读(74)  评论(0编辑  收藏  举报