全部產品
Search
文件中心

Alibaba Cloud Service Mesh:接入gRPC協議的自訂授權服務

更新時間:Jan 13, 2025

當您需要對使用gRPC協議通訊的服務進行細粒度的存取控制時,可以使用自訂授權服務功能,根據特定業務需求定製授權機制,在服務間互相通訊時加入鑒權流程,確保只有經過認證和授權的請求才能訪問相應的服務資源,提高服務間通訊的安全性。本文以httpbin應用和sleep應用為例,介紹如何?接入gRPC協議的自訂授權服務。

前提條件

已添加叢集到ASM執行個體

步驟一:部署自訂授權服務

在叢集中部署自訂授服務。該服務需遵循Istio自訂鑒權服務介面規範,支援HTTP和gRPC協議,用於實現自訂鑒權邏輯。本文使用的樣本服務需求請求必須帶有x-ext-authz: allow要求標頭,才能通過鑒權訪問成功。

說明

本文提供了自訂授權服務樣本。您也可以參考本樣本應用的代碼,建立自己的自訂授權服務。具體內容,請參見自訂授權

  1. 使用以下內容,建立ext-authz.yaml

    展開查看ext-authz.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    # Example configurations for deploying ext-authz server separately in the mesh.
    
    apiVersion: v1
    kind: Service
    metadata:
      name: ext-authz
      labels:
        app: ext-authz
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 8000
      - name: grpc
        port: 9000
        targetPort: 9000
      selector:
        app: ext-authz
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ext-authz
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ext-authz
      template:
        metadata:
          labels:
            app: ext-authz
        spec:
          containers:
          - image: istio/ext-authz:0.6
            imagePullPolicy: IfNotPresent
            name: ext-authz
            ports:
            - containerPort: 8000
            - containerPort: 9000
    ---
  2. 通過kubectl串連叢集,執行以下命令,在叢集中部署自訂授權服務。

    關於如何通過kubectl串連叢集,請參見擷取叢集KubeConfig並通過kubectl工具串連叢集

    kubectl apply -f ext-authz.yaml

    預期輸出:

    service/ext-authz created
    deployment.apps/ext-authz created
  3. 執行以下命令, 驗證應用是否正常工作。

    kubectl logs "$(kubectl get pod -l app=ext-authz -n default -o jsonpath={.items..metadata.name})" -n default -c ext-authz

    預期輸出:

    2023/12/20 08:15:39 Starting gRPC server at [::]:9000
    2023/12/20 08:15:39 Starting HTTP server at [::]:8000

    返回以上結果,說明自訂授權服務部署成功。

  4. 擷取ext-authz應用的gRPC協議連接埠。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇網路 > 服務

    3. 服務頁面,單擊ext-authz

      端點地區,可以看到gRPC協議的連接埠為9000。

步驟二:部署樣本應用

  1. 使用以下內容,建立httpbin.yaml

    展開查看httpbin.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # httpbin service
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: httpbin
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
        service: httpbin
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 80
      selector:
        app: httpbin
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpbin
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpbin
          version: v1
      template:
        metadata:
          labels:
            app: httpbin
            version: v1
        spec:
          serviceAccountName: httpbin
          containers:
          - image: docker.io/kennethreitz/httpbin
            imagePullPolicy: IfNotPresent
            name: httpbin
            ports:
            - containerPort: 80
                            
  2. 執行以下命令,在叢集中部署httpbin應用。

    kubectl apply -f httpbin.yaml
  3. 使用以下內容,建立sleep.yaml

    展開查看sleep.yaml

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # Sleep service
    ##################################################################################################
    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: curlimages/curl
            command: ["/bin/sleep", "3650d"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
    ---
                            
  4. 執行以下命令,在叢集中部署sleep應用。

    kubectl apply -f sleep.yaml

步驟三:使用gRPC協議對接自訂授權服務

您需要將步驟一部署的服務聲明到Service Mesh中,使Service Mesh可以使用該服務進行鑒權。

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 自訂授權服務,然後單擊關聯自訂授權服務

  3. 關聯自訂授權服務頁面,單擊基於envoy.ext_authz實現的自訂授權服務(HTTP或gRPC協議)頁簽,進行相關配置,然後單擊建立

    類型

    配置項

    說明

    必選參數

    協議

    選擇自訂授權應用的協議。本文選擇GRPC

    名稱

    自訂授權服務名稱。本文設定為test

    服務地址

    輸入自訂授權應用的服務地址<應用程式名稱>.<命名空間名稱>.svc.<叢集網域名稱>。本文設定為ext-authz.default.svc.cluster.local

    服務連接埠

    輸入自訂授權應用的服務連接埠。本文設定為9000

    逾時時間

    如果鑒權應用未在該時間內返回,則認為鑒權服務不可用。本文設定為10秒。

    選擇性參數

    鑒權服務不可用時允許存取請求

    是否在鑒權服務不可用時允許存取請求。若啟用該選項,則鑒權服務不可用時請求被允許存取。

    鑒權服務不可用自訂錯誤碼

    該選項僅在關閉鑒權服務不可用時允許存取請求時可選。若啟用該選項,需填寫錯誤碼,在鑒權服務不可用時,該錯誤碼將被返回至調用端。

    在鑒權請求中攜帶請求Body

    啟用該選項後,需填寫鑒權請求攜帶Body的最大長度。若啟用允許將不完整訊息發往鑒權服務,當被鑒權請求Body大於設定的最大長度時,從最大長度處截取,並將截取後的Body發往鑒權服務。

步驟四:建立授權策略

您需要建立授權策略來配置需要鑒權的請求操作。

  1. 登入ASM控制台,在左側導覽列,選擇服務網格 > 網格管理

  2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇網格資訊安全中心 > 授權策略,然後單擊建立

  3. 建立頁面,進行相關配置,然後單擊建立

    配置項

    說明

    名稱

    自訂授權策略名稱稱,本文設定為test1

    策略類型

    選擇自訂授權服務

    自訂授權服務

    選擇grpcextauth-test(GRPC)

    命名空間

    工作負載生效頁簽,選擇default命名空間。

    生效範圍

    選擇Service

    工作負載

    選擇httpbin

    請求匹配規則

    添加請求目標地區,開啟HTTP路徑(Paths)開關,設定值為/headers

步驟五:驗證自訂授權是否成功

  1. 執行以下命令,訪問httpbin.default:8000/ip

    kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/ip" -s -o /dev/null -w "%{http_code}\n"

    返回200,說明沒有觸發鑒權。

  2. 執行以下命令,帶有x-ext-authz: deny要求標頭訪問httpbin.default:8000/headers

    kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -ndefault -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: deny" -s

    預期輸出:

    denied by ext_authz for not found header `x-ext-authz: allow` in the request

    預期輸出表明觸發鑒權,但是鑒權未通過。

  3. 執行以下命令,帶有x-ext-authz: allow要求標頭訪問httpbin.default:8000/headers

    kubectl exec "$(kubectl get pod -l app=sleep -n default -o jsonpath={.items..metadata.name})" -c sleep -n default -- curl "http://httpbin.default:8000/headers" -H "x-ext-authz: allow" -s

    預期輸出:

    {
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin.default:8000",
        "User-Agent": "curl/8.5.0",
        "X-Envoy-Attempt-Count": "1",
        "X-Ext-Authz": "allow",
        "X-Ext-Authz-Check-Result": "allowed",
        "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=c3e5364e87add0f4f69e6b0d029f5961b404c8f209bf9004b3d21a82cf67****;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
      }
    }

    預期輸出表明觸發鑒權,並且鑒權通過。訪問httpbin.default:8000/headers時,請求中必須帶有x-ext-authz: allow才能成功訪問,說明自訂授權成功。

相關操作