L7认证与鉴权

Ambient模式中,由于4层和7层的分离架构,导致认证和授权的配置模型与原Sidecar模式不同。本文介绍如何使用7层授权策略。

前提条件

已部署ASM网关和应用,且成功验证基本功能。具体操作,请参见入门示例的前提条件和步骤一。

使用限制

  • 授权策略在Waypoint代理中的使用限制如下:

    • action字段不支持CUSTOM,即Waypoint代理不支持自定义授权服务。

    • source字段中不支持ipBlocks

  • 存在Waypoint代理时,Ztunnel代理会允许所有来自Waypoint代理的请求通过。此时,授权策略需要绑定给指定的Waypoint代理。

准备工作

ASM 1.21及以下版本

  1. 执行以下命令,为productpage部署Waypoint。

    istioctl x waypoint apply --service-account bookinfo-productpage
  2. 执行以下命令,查看对应的Waypoint Pod。

    kubectl get pod --show-labels | grep waypoint

    预期输出:

    bookinfo-productpage-istio-waypoint-6c579dd48d-l****   1/1     Running   0          91s    gateway.istio.io/managed=istio.io-mesh-controller,istio.io/gateway-name=bookinfo-productpage,pod-template-hash=6c579dd48d,service.istio.io/canonical-name=bookinfo-productpage-istio-waypoint,service.istio.io/canonical-revision=latest,sidecar.istio.io/inject=false

ASM 1.22及以上版本

  1. 使用以下内容,部署Gateway。

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      labels:
        istio.io/waypoint-for: service
      name: waypoint
      namespace: default
    spec:
      gatewayClassName: istio-waypoint
      listeners:
      - name: mesh
        port: 15008
        protocol: HBONE
  2. 执行以下命令,为productpage服务开启waypoint。

    kubectl label service productpage istio.io/use-waypoint=waypoint

示例一:存在Waypoint时,Ztunnel上的授权策略失效

存在Waypoint时,Ztunnel将会允许所有来自当前服务Waypoint的流量通过,此时再将授权策略应用到Ztunnel上(授权策略的selector选中了业务Pod)时,该授权策略不会生效。

  1. 使用以下内容,创建productpage-viewer.yaml。

    以下授权策略作用于Ztunnel,禁止访问productpage的9080端口。

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: productpage-viewer
     namespace: default
    spec:
     selector:
       matchLabels:
         app: productpage
     action: DENY
     rules:
     - to:
       - operation:
           ports:
           - "9080"
  2. 在ASM实例对应的kubeconfig环境下,执行以下命令,创建授权策略。

    kubectl apply -f productpage-viewer.yaml
  3. 验证授权策略是否生效。

    1. 执行以下命令,进行访问测试。

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

      预期输出:

      command terminated with exit code 56
    2. 执行以下命令,进行访问测试。

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

      预期输出:

      <title>Simple Bookstore App</title>

    本测试和不存在Waypoint的示例二:禁止访问productpage的9080端口使用了同样的授权策略,但本测试所有访问均成功。

    以上结果说明当配置Waypoint后,之前Ztunnel上的所有策略都会失效。

  4. 将授权策略productpage-viewer.yaml修改为如下内容,然后执行kubectl apply -f productpage-viewer.yaml命令进行部署。

    ASM 1.21及以下

    以下YAML修改了selector字段。

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: productpage-viewer
     namespace: default
    spec:
     selector:
       matchLabels:
         istio.io/gateway-name: bookinfo-productpage
     action: DENY
     rules:
     - to:
       - operation:
           ports:
           - "9080"

    ASM 1.22及以上

    以下YAML修改为直接引用Service。

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: productpage
      action: DENY
      rules:
      - to:
        - operation:
            ports:
            - "9080"

  5. 验证授权策略是否生效。

    1. 执行以下命令,进行访问测试。

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

      预期输出:

      RBAC: access denied%
    2. 执行以下命令,进行访问测试。

      kubectl exec deploy/notsleep -- curl -s http://productpage:9080/

      预期输出:

      RBAC: access denied%

      此处返回的报错信息RBAC: access denied%和L4鉴权的示例二:禁止访问productpage的9080端口不同。这个错误实际由productpage的Waypoint返回。Waypoint发现9080端口不允许访问,于是返回一个HTTP RBAC错误,实际的状态码应为403。

  6. 执行以下命令,清除授权策略。

    kubectl delete authorizationpolicy productpage-viewer

示例二:禁止sleep Pod的IP直接访问productpage

目前配置在Waypoint上的授权策略不支持ipBlocks字段,只支持remoteIpBlocks。请求经过网关只能配置remoteIpBlocks字段进行匹配。

  1. 使用以下内容,创建productpage-viewer.yaml,禁止sleep Pod访问productpage。

    ASM 1.21及以下

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: productpage-viewer
     namespace: default
    spec:
     selector:
       matchLabels:
         istio.io/gateway-name: bookinfo-productpage
     action: DENY
     rules:
     - from:
       - source:
           remoteIpBlocks:
           - "${sleep Pod IP}"

    ASM 1.22及以上

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: productpage
      action: DENY
      rules:
      - from:
        - source:
            remoteIpBlocks:
            - "${sleep Pod IP}"
  2. 在ASM实例对应的kubeconfig环境下,执行以下命令,创建授权策略。

    kubectl apply -f productpage-viewer.yaml
  3. 验证授权策略是否生效。

  4. 执行以下命令,进行访问测试。

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

    预期输出:

    HTTP/1.1 403 Forbidden
    content-length: 19
    content-type: text/plain
    date: Fri, 19 Jul 2024 08:17:08 GMT
    server: istio-envoy

    预期输出表明sleep Pod不可以直接访问productpage,也不可以通过网关访问。

  5. 执行以下命令,清除授权策略。

    kubectl delete authorizationpolicy productpage-viewer

示例三:限制不允许使用HEAD方法访问/productpage路径

  1. 使用以下内容,创建productpage-viewer.yaml。

    ASM 1.21及以下

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      selector:
        matchLabels:
          istio.io/gateway-name: bookinfo-productpage
      action: DENY
      rules:
      - to:
        - operation:
            methods: ["HEAD"]
            paths: ["/productpage"]

    ASM 1.22及以上

    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-viewer
      namespace: default
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: productpage
      action: DENY
      rules:
      - to:
        - operation:
            methods:
            - "HEAD"
            paths:
            - "/productpage"
  2. 在ASM实例对应的kubeconfig环境下,执行以下命令,创建授权策略。

    kubectl apply -f productpage-viewer.yaml
  3. 验证授权策略是否生效。

    1. 执行以下命令,使用HEAD方法访问/productpage路径进行测试。

      kubectl exec deploy/sleep -- curl -s productpage:9080/productpage -I

      预期输出:

      HTTP/1.1 403 Forbidden
      content-length: 19
      content-type: text/plain
      date: Thu, 15 Aug 2024 12:20:51 GMT
      server: istio-envoy
    2. 执行以下命令,使用GET方法访问/productpage路径进行访问测试。

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

      预期输出:

      <title>Simple Bookstore App</title>

      访问/productpage路径成功

    3. 执行以下命令,使用HEAD方法访问/路径进行访问测试。

      kubectl exec deploy/sleep -- curl -s productpage:9080/ -I

      预期输出:

      HTTP/1.1 200 OK
      server: istio-envoy
      date: Thu, 15 Aug 2024 12:23:17 GMT
      content-type: text/html; charset=utf-8
      content-length: 1743
      x-envoy-upstream-service-time: 2
  4. 执行以下命令,清除授权策略。

    kubectl delete authorizationpolicy productpage-viewer