在 GKE 設定 sidecar 的授權政策

本頁面說明如何在 GKE 的 Cloud Service Mesh sidecar 上,設定不同類型的授權政策。

事前準備

您應熟悉 Gateway API 和授權擴充功能。

建立授權政策前,請先完成下列步驟:

  1. 登入 Google Cloud 帳戶。如果您未曾使用過 Google Cloud,歡迎 建立帳戶,親自體驗實際使用我們產品的成效。新客戶還能獲得價值 $300 美元的免費抵免額,用於執行、測試及部署工作負載。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Network Security, Network Services APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Network Security, Network Services APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

命名空間層級 AuthzPolicy

如要拒絕整個命名空間的預期流量模式,請設定授權政策,拒絕傳送至命名空間中所有工作負載的任何傳入 HTTP 要求:

cat >ns-authz-policy-deny.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: ns-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector: {}
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/bad_token"
  action: DENY
  enforcementLevel: L7
EOF
kubectl apply -f ns-authz-policy-deny.yaml

空白的 selector: {} 會指定命名空間中的所有 Pod。

如要允許整個命名空間的預期流量模式,請設定授權政策,允許任何傳入 HTTP 要求傳送至命名空間中的所有工作負載:

cat >ns-authz-policy-allow.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: ns-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector: {}
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/headers"
        methods: ["GET"]
  action: ALLOW
  enforcementLevel: L7
EOF
kubectl apply -f ns-authz-policy-allow.yaml

空白的 selector: {} 會指定命名空間中的所有 Pod。

拒絕傳入工作負載的要求

如果工作負載只應發出外送呼叫 (例如 Cron 工作),請設定授權政策,拒絕任何傳入工作負載的 HTTP 要求:

cat >deny-path-authz-policy.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: my-workload-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector:
      matchLabels:
        app: EXAMPLE_APP
  rules:
  - to:
      operations:
      - paths:
        - type: Prefix
          value: "/deny_path"
  action: DENY
  enforcementLevel: L7
EOF
kubectl apply -f deny-path-authz-policy.yaml

輸出內容大致如下:

gcpauthzpolicy.networking.gke.io/my-workload-authz created

套用這項政策後,凡是傳入 HTTP 要求,只要路徑為 /deny_path,且 Pod 符合 app: EXAMPLE_APP,就會遭到拒絕,呼叫端也會收到 HTTP 403 Forbidden 回應代碼。

允許對工作負載提出特定傳入要求

您也可以設定 ALLOW 政策,只允許符合特定條件的要求,並拒絕其他要求。

以下範例會在 example-app Deployment 設定授權政策,只允許來自具有 spiffe://cluster.local/NAMESPACE/pod1 身分的 Pod 的 mTLS 要求。

cat >allow-authz-policy.yaml <<EOF
apiVersion: networking.gke.io/v1
kind: GCPAuthzPolicy
metadata:
  name: my-workload-authz
  namespace: NAMESPACE
spec:
  targetRefs:
  - group: ""
    kind: Pod
    selector:
      matchLabels:
        app: EXAMPLE_APP
  rules:
  - from:
      sources:
      - principals:
        - principal:
            type: Exact
            value: "spiffe://cluster.local/NAMESPACE/pod1"
  action: ALLOW
  enforcementLevel: L7
EOF
kubectl apply -f allow-authz-policy.yaml

輸出內容大致如下:

gcpauthzpolicy.networking.gke.io/my-workload-authz created

只有使用 mTLS 驗證且提供確切 SPIFFE 身分 spiffe://cluster.local/NAMESPACE/pod1 的傳入要求,才會收到 HTTP 200 OK。任何其他要求都會遭到 Proxy 拒絕,並傳回 HTTP 403 Forbidden。

委派給外部授權引擎

您可以自備授權引擎,並設定 Cloud Service Mesh,將工作負載的所有授權決策委派給設定的引擎。

  1. 如果尚未安裝 GCPAuthzExtension CRD,請先安裝:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/main/config/crd/networking.gke.io_gcpauthzextensions.yaml
    
  2. 在 Kubernetes 中部署支援 ext_proc gRPC 通訊協定的呼叫式授權擴充功能工作負載,並設定授權擴充功能資源:

    cat >authz-extension.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzExtension
    metadata:
      name: my-authz-ext
      namespace: NAMESPACE
    spec:
      backendRef:
        group: ""
        kind: Service
        name: authz-service
        port: PORT
      authority: "authz-service.NAMESPACE.svc.cluster.local"
      forwardHeaders:
      - Authorization
      failOpen: false
      timeout: "100ms"
      wireFormat: ExtProcGRPC
    EOF
    kubectl apply -f authz-extension.yaml
    

    更改下列內容:

    • NAMESPACE:authz-service 服務和工作負載的命名空間。
    • PORT:提供 ext_proc gRPC API 的 authz-service 服務通訊埠。

    這個指令會建立以呼叫為基礎的授權擴充功能,並以 Kubernetes 服務 authz-service 的形式執行。

    輸出內容大致如下:

    gcpauthzextension.networking.gke.io/my-authz-ext created
    
  3. 設定授權政策,將工作負載的授權決策委派給先前設定的授權擴充功能:

    cat >authz-policy.yaml <<EOF
    apiVersion: networking.gke.io/v1
    kind: GCPAuthzPolicy
    metadata:
      name: my-workload-authz
      namespace: NAMESPACE
    spec:
      targetRefs:
      - group: ""
        kind: Pod
        selector:
          matchLabels:
            app: EXAMPLE_APP
      rules:
      - from:
          sources:
          - principals:
            - principal:
                type: Exact
                value: "spiffe://cluster.local/NAMESPACE/pod1"
        to:
          operations:
          - paths:
            - type: Exact
              value: "/api/payments-schedule"
      action: CUSTOM
      enforcementLevel: L7
      customProviders:
        extensionRefs:
        - group: networking.gke.io
          kind: GCPAuthzExtension
          name: my-authz-ext
    EOF
    kubectl apply -f authz-policy.yaml
    

    輸出內容大致如下:

    gcpauthzpolicy.networking.gke.io/my-workload-authz created
    

    Proxy 會等待授權擴充功能回應,再將要求轉送至應用程式。如果擴充功能因錯誤而結束呼叫,導致要求遭拒,或者呼叫失敗或逾時,且 failOpen 為 false,呼叫端就會收到 HTTP 500 回應。如果擴充功能立即傳送回應,呼叫端會收到該回應的狀態碼。