L4认证与鉴权

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

前提条件

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

使用限制

  • 授权策略在Ztunnel中的使用限制如下:

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

    • source字段中不支持requestPrincipalsremoteIpBlocks

    • operation字段中除ports以外的所有字段均不支持。

  • 当不存在Waypoint代理时,Ztunnel代理是授权策略的执行者。此时,授权策略需要绑定给指定的工作负载。

  • Ztunnel只是一个4层代理,如果在其上配置包含7层规则的授权策略,只有4层的规则会生效。

示例一:productpage只允许被网关和sleep访问

本示例主要验证Ztunnel代理能否正确执行principals鉴权逻辑。具体操作,请参见入门示例

测试完成后,请执行以下命令,清除授权策略。

kubectl delete authorizationpolicy productpage-viewer

示例二:禁止访问productpage的9080端口

本示例主要验证Ztunnel代理能否正确执行目标端口鉴权逻辑。

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

    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://$GATEWAY_HOST/productpage"

      预期输出:

      upstream connect error or disconnect/reset before headers. reset reason: connection termination%
    2. 执行以下命令,进行访问测试

      kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage"

      预期输出:

      upstream connect error or disconnect/reset before headers. reset reason: connection termination%
    3. 执行以下命令,进行访问测试

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

      预期输出:

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

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

      预期输出:

      command terminated with exit code 56

      可以看到,所有Pod都不能访问productpage的9080端口。

      前两个测试命令通过网关访问productpage的请求报错为upstream connect error or disconnect/reset before headers. reset reason: connection termination%,这个错误实际由ASM网关返回。网关连接不上后端服务(后端服务拒绝网关连接9080端口),就会报一个HTTP错误(实际状态码为503)。

      后两个测试命令的返回值为command terminated with exit code 56,由curl命令返回。curl命令直接和productpage建立连接,但连接失败,因此没有HTTP错误,和直接通过网关访问的错误有区别。

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

    kubectl delete authorizationpolicy productpage-viewer

示例三:不允许sleep Pod的IP访问productpage

本示例主要验证Ztunnel代理能否正确执行源IP鉴权逻辑。

  1. 执行以下命令,查看sleep Pod的IP。

    kubectl get pod -o wide | grep sleep

    预期输出:

    notsleep-5fb85fb789-z****         1/1     Running   0          48m   10.0.67.92   cn-hangzhou.10.0.67.41   <none>           <none>
    sleep-bc9998558-z****             1/1     Running   0          48m   10.0.67.91   cn-hangzhou.10.0.67.42   <none>           <none>

    预期输出表明当前测试环境的sleep Pod的IP为10.0.67.91。每个环境里的实际Pod IP可能不同。

  2. 使用以下内容,创建productpage-viewer.yaml,限制productpage拒绝来自sleep Pod IP的请求。

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

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

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

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

      预期输出:

      <title>Simple Bookstore App</title>
    2. 执行以下命令,进行访问测试。

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

      预期输出:

      <title>Simple Bookstore App</title>
    3. 执行以下命令,进行访问测试。

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

      预期输出:

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

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

      预期输出:

      <title>Simple Bookstore App</title>

      可以看到只使用Ztunnel代理,没有Waypoint代理,并不能实现禁止sleep Pod通过网关访问productpage。因为授权策略中的remoteIpBlocks字段依赖请求的X-Forwarded-For Header实现,Ztunnel只是一个4层代理。

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

    kubectl delete authorizationpolicy productpage-viewer

示例四:禁止istio-system命名空间的Pod访问productpage

本示例主要验证Ztunnel代理能否正确执行源命名空间鉴权逻辑。

  1. 使用以下内容,创建productpage-viewer.yaml,禁止istio-system命名空间下的Pod访问productpage。

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

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

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

      kubectl exec deploy/sleep -- curl -s "http://$GATEWAY_HOST/productpage"

      预期输出:

      upstream connect error or disconnect/reset before headers. reset reason: connection termination%
    2. 执行以下命令,进行访问测试

      kubectl exec deploy/notsleep -- curl -s "http://$GATEWAY_HOST/productpage"

      预期输出:

      upstream connect error or disconnect/reset before headers. reset reason: connection termination%
    3. 执行以下命令,进行访问测试

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

      预期输出:

      <title>Simple Bookstore App</title>
    4. 执行以下命令,进行访问测试

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

      预期输出:

      <title>Simple Bookstore App</title>

      ASM网关部署在istio-system命名空间下。可以看到,授权策略创建成功后,sleep和notsleep无法通过网关访问productpage,但是可以直接访问productpage。

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

    kubectl delete authorizationpolicy productpage-viewer