为应用配置授权策略

ASM开启Ambient模式后,您可以使用4层或7层授权策略保护应用程序访问,并根据工作负载的ServiceAccount对流量实施访问控制。本文介绍如何为Bookinfo应用配置4层和7层授权策略。

前提条件

已完成部署示例应用程序并开启ambient实现加密通信中的全部操作。

准备工作

开始本文的配置前,您需要在集群中部署Sleep应用作为另一个客户端。

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sleep
---
apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
    service: sleep
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: sleep
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sleep
  template:
    metadata:
      labels:
        app: sleep
    spec:
      terminationGracePeriodSeconds: 0
      serviceAccountName: sleep
      containers:
      - name: sleep
        image: registry.cn-hangzhou.aliyuncs.com/acs/curl:8.1.2
        command: ["/bin/sleep", "infinity"]
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: /etc/sleep/tls
          name: secret-volume
      volumes:
      - name: secret-volume
        secret:
          secretName: sleep-secret
          optional: true
EOF

配置4层授权策略

4层代理称为Ztunnel,使用Rust语言开发,旨在处理3层和4层流量,比如mTLS、身份验证、4层鉴权和可观测。它以Daemonset的形式部署,同一节点上的Pod共享一个Ztunnel,所有进出这些Pod的流量都会被Ztunnel处理。

  1. 为带有app: productpage标签的Pod创建授权策略,仅允许来自istio-ingressgateway ServiceAccount的客户端访问productpage服务。

    kubectl apply -f - <<EOF
    apiVersion: security.istio.io/v1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-ztunnel
      namespace: default
    spec:
      selector:
        matchLabels:
          app: productpage
      action: ALLOW
      rules:
      - from:
        - source:
            principals:
            - cluster.local/ns/istio-system/sa/istio-ingressgateway
    EOF
  2. 在浏览器中访问http://{入口网关的IP地址}/productpage查看Bookinfo应用,可以看到流量正常。

  3. 通过sleep应用访问Bookinfo应用。

    kubectl exec deployment/sleep -- curl -s "http://productpage:9080/productpage" -I

    预期输出:

    command terminated with exit code 56

    可以看到访问被拒绝。由于Ztunnel的授权策略工作在4层,所以您并不会看到被拒绝的HTTP状态码。

配置7层授权策略

配置7层授权策略需要部署一个Waypoint代理,然后为命名空间配置istio.io/use-waypoint=waypoint标签,使命名空间内所有Service的流量都必须通过Waypoint。

  1. 部署Waypoint。

    kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: waypoint
    spec:
      gatewayClassName: istio-waypoint
      listeners:
      - name: mesh
        port: 15008
        protocol: HBONE
    EOF
  2. 查看Waypoint代理的状态,直到PROGRAMMEDTrue

    kubectl get gtw

    预期输出:

    NAME       CLASS            ADDRESS        PROGRAMMED   AGE
    waypoint   istio-waypoint   172.16.99.15   True         2m29s
  3. 为命名空间添加标签。

    kubectl label namespace default istio.io/use-waypoint=waypoint --overwrite
  4. 配置授权策略,明确允许sleep应用只能通过GET方法访问productpage应用。

    1. 创建7层授权策略。

      kubectl apply -f - <<EOF
      apiVersion: security.istio.io/v1
      kind: AuthorizationPolicy
      metadata:
        name: productpage-waypoint
        namespace: default
      spec:
        targetRefs:
        - kind: Service
          group: ""
          name: productpage
        action: ALLOW
        rules:
        - from:
          - source:
              principals:
              - cluster.local/ns/default/sa/sleep
          to:
          - operation:
              methods: ["GET"]
      EOF
      说明

      7层授权策略不再使用标签来选择生效的服务,而是通过targetRefs来表示在Waypoint上对哪个服务执行当前策略。规则的前半部分和Ztunnel的授权策略类似,但是新增了to字段来限制HTTP方法。

    2. 更新4层授权策略,允许接受来自Waypoint的流量。

      kubectl apply -f - <<EOF
      apiVersion: security.istio.io/v1
      kind: AuthorizationPolicy
      metadata:
        name: productpage-ztunnel
        namespace: default
      spec:
        selector:
          matchLabels:
            app: productpage
        action: ALLOW
        rules:
        - from:
          - source:
              principals:
              - cluster.local/ns/istio-system/sa/istio-ingressgateway
              - cluster.local/ns/default/sa/waypoint
      EOF
  5. 验证授权策略。

    1. 使用非GET方法从sleep应用访问Bookinfo应用。

      kubectl exec deploy/sleep -- curl -s "http://productpage:9080/productpage" -X DELETE

      预期输出:

      RBAC: access denied
    2. reviews-v1服务访问Bookinfo应用。

      kubectl exec deploy/reviews-v1 -- curl -s http://productpage:9080/productpage

      预期输出:

      RBAC: access denied
    3. 使用GET方法从sleep应用访问Bookinfo应用。

      kubectl exec deploy/sleep -- curl -s http://productpage:9080/productpage | grep -o "<title>.*</title>"

      预期输出:

      <title>Simple Bookstore App</title>

    可以看到,上述请求的结果与策略配置预期一致,策略正常生效。