すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:ASM セキュリティポリシーを使用して外部 OPA エンジンにアクセスする

最終更新日:Jan 14, 2025

Service Mesh(ASM)を使用すると、Istio ネイティブセキュリティリソースをカプセル化し、セキュリティポリシー機能を提供できます。一般的なシナリオでは、セキュリティ設定を簡単に完了できます。ASM は Open Policy Agent(OPA)と統合されています。 OPA を使用してアクセス制御ポリシーを定義し、アプリケーションへのきめ細かいアクセス制御を実装できます。このトピックでは、ASM セキュリティポリシーを使用してポッド外の OPA エンジンにアクセスする方法について説明します。

前提条件

機能の説明

デフォルトでは、OPA は ASM でサイドカーモードでデプロイされます。 OPA を有効にした後にアプリケーションポッドを再起動すると、ASM はアプリケーションポッドに OPA コンテナを挿入します。その後、アプリケーションコンテナへのすべてのリクエストは OPA によって認証されます。サイドカーモードでは、Istio プロキシは同じポッド内の OPA にアクセスします。したがって、レイテンシは低く、このモードはレイテンシの影響を受けやすいサービスに適しています。

ただし、サイドカーモードには次の欠点があります。大量のリソースが占有されます。 OPA コンテナがポッドに挿入されると、ポッドを再起動する必要があります。リクエストは柔軟な方法でアプリケーションにアクセスできません。集中モードの OPA は、これらの側面でサイドカーモードの OPA を補完できます。集中モードの OPA には次の利点があります。リソースの使用量が少なくなります。 OPA コンテナのデプロイとアプリケーションへのリクエストアクセスにポッドを再起動する必要はありません。アプリケーションへの特定のリクエストに OPA ポリシーを使用できます。このトピックでは、アプリケーションへのリクエストの認証のために集中モードで OPA をデプロイする方法について説明します。

OPA部署方式.png

ステップ 1:OPA をデプロイする

  1. asm-opa.yaml という名前のファイルを作成し、次の内容をファイルにコピーします。

    YAML コードは、OPA サービス、OPA デプロイメント、およびシークレットをデプロイします。

    種類

    説明

    デプロイメント

    • イメージ registry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-static 内のリージョン ID を、クラスターがデプロイされているリージョンの ID に置き換えます。

    • デフォルトでは、OPA エンジン(--set=decision_logs.console=true)のログ記録が有効になっています。これはデバッグに役立ちます。

    シークレット

    シークレットは、次の OPA ポリシーを定義します。

    • リクエストのパスが health の場合、リクエストは許可されます。

    • リクエストのメソッドが HEAD の場合、リクエストは許可されます。

    • リクエストのユーザー名が alice の場合、リクエストは許可されます。

      説明

      ユーザー名は、リクエストの Authorization ヘッダーに Authorization: Basic ${user name: Base64-encoded password string} の形式で含まれています。

    asm-opa.yaml の内容を表示する

    apiVersion: v1
    kind: Service
    metadata:
      name: asm-opa
      labels:
        app: opa
    spec:
      ports:
        - name: grpc
          port: 9191
          targetPort: 9191
          protocol: TCP
        - name: http
          port: 8181
          targetPort: 8181
          protocol: TCP
      selector:
        app: opa
    ---
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: opa
      labels:
        app: opa
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: opa
      template:
        metadata:
          labels:
            app: opa
          annotations:
            sidecar.istio.io/inject: "false"
        spec:
          containers:
            - name: opa
              image: registry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-static  // クラスターがデプロイされているリージョンのレジストリを使用します
              securityContext:
                runAsUser: 1111
              volumeMounts:
                - readOnly: true
                  mountPath: /policy
                  name: opa-policy
              args:
                - "run"
                - "--server"
                - "--addr=0.0.0.0:8181"
                - "--diagnostic-addr=0.0.0.0:8282"
                - "--set=plugins.envoy_ext_authz_grpc.addr=:9191"
                - "--set=plugins.envoy_ext_authz_grpc.path=asm/authz/allow"
                - "--set=decision_logs.console=true" // デバッグを容易にするためにログを有効にします
                - "--ignore=.*"
                - "/policy/policy.rego"
              ports:
                - containerPort: 9191
                  protocol: TCP
              resources:
                limits:
                  cpu: "0"
                  memory: "0"
          volumes:
            - name: opa-policy
              secret:
                secretName: opa-policy
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: opa-policy
    type: Opaque
    stringData:
      policy.rego: |
        package asm.authz
    
        import future.keywords
    
        import input.attributes.request.http as http_request // リクエストヘッダーからHTTP属性を取得します
        import input.parsed_path  // リクエストパスを取得します
    
        default allow := false
    
        allow if {
          parsed_path[0] == "health" // healthパスへのリクエストを許可します
        }
    
        allow if {
          http_request.method == "HEAD" // HEADメソッドのリクエストを許可します
        }
    
        allow if {
          user_name == "alice" // ユーザーaliceのリクエストを許可します
        }
    
        user_name := parsed if { // Authorizationヘッダーからユーザー名を取得します
          [_, encoded] := split(http_request.headers.authorization, " ")
          [parsed, _] := split(base64url.decode(encoded), ":")
        }
    
  2. kubectl を使用して、kubeconfig ファイルの情報に基づいて Container Service for Kubernetes(ACK)クラスターに接続し、次のコマンドを実行して OPA をデプロイします。

    kubectl apply -f asm-opa.yaml

ステップ 2:ASM セキュリティポリシーを OPA に関連付ける

  1. [ASM コンソール] にログインします。左側のナビゲーションペインで、[サービスメッシュ] > [メッシュ管理] を選択します。

  2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、[メッシュセキュリティセンター] > [ASM セキュリティポリシー] を選択します。

  3. [ASM セキュリティポリシー] ページで、[作成] をクリックします。[ASM セキュリティポリシーの作成] ダイアログボックスで、[カスタム認証サービス] カードをクリックし、[OK] をクリックします。

  4. カスタム認証サービスを設定します。

    1. [カスタム認証サービスの作成] ページで、ステップ 1 でデプロイされた OPA 認証サービスに関する情報を設定し、[次へ] をクリックします。

      创建自定义授权服务.png

    2. [ワークロードと一致ルール] ステップで、[ワークロードグループの追加] をクリックします。[新しいワークロードグループ] ダイアログボックスで、[ワークロードグループ名] を設定し、[ワークロードの追加] をクリックします。

    3. [ワークロードの追加] ダイアログボックスで、[ワークロードスコープ] を選択し、[名前空間][default] に設定し、[ワークロードタイプ][サービス] に設定します。次に、[ワークロードの選択] セクションで [httpbin] を選択し、Dingtalk_20230302182310.png アイコンをクリックして、[OK] をクリックします。添加工作负载.png

    4. [新しいワークロードグループ] ダイアログボックスの [一致ルールリスト] セクションで、[一致モード][選択したリクエストを認証する必要があります] に設定し、[一致ルール][カスタム一致ルール] に設定します。[パス] スイッチをオンにし、フィールドに /status/* と入力して、[OK] をクリックします。

      新建工作负载组.png

    5. [ワークロードと一致ルール] ステップで、[送信] をクリックします。

      次の図は、セキュリティポリシーが作成され、OPA に関連付けられた後のページを示しています。ASM安全策略创建成功.png

ステップ 3:HTTPBin アプリケーションへのアクセスをテストする

  1. 次のコマンドを実行して、/ パスにアクセスします。

    curl ${IP address of the ASM gateway}/ -I -X GET

    予期される出力:

    HTTP/1.1 200 OK
    server: istio-envoy
    date: Tue, 25 Jul 2023 08:30:58 GMT
    content-type: text/html; charset=utf-8
    content-length: 9593
    access-control-allow-origin: *
    access-control-allow-credentials: true
    x-envoy-upstream-service-time: 2

    出力は、パスへのアクセスリクエストに認証が不要であることを示しています。

  2. 有効なパラメーターなしで次のコマンドを実行して、/status/201 パスにアクセスします。

    curl ${IP address of the ASM gateway}/status/201 -I -X GET

    予期される出力:

    HTTP/1.1 403 Forbidden
    date: Tue, 25 Jul 2023 08:31:18 GMT
    server: istio-envoy
    content-length: 0
    x-envoy-upstream-service-time: 1

    出力は、有効なパラメーターのないアクセスリクエストが拒否されたことを示しています。

  3. 有効なパラメーターを使用して次のコマンドを実行して、/status/201 パスにアクセスします。

    curl ${IP address of the ASM gateway}/status/201 -I -X GET --user alice:testpassword

    予期される出力:

    HTTP/1.1 201 Created
    server: istio-envoy
    date: Tue, 25 Jul 2023 08:31:38 GMT
    content-type: text/html; charset=utf-8
    access-control-allow-origin: *
    access-control-allow-credentials: true
    content-length: 0
    x-envoy-upstream-service-time: 3

    出力は、有効なパラメーターを含むアクセスリクエストが許可されたことを示しています。

ステップ 4:OPA ポリシーを更新する

OPA エンジンの HTTP API を呼び出して、OPA ポリシーを更新します。

  1. 次のコマンドを実行して、bob という名前のユーザーのみが HTTP 経由で HTTPBin アプリケーションにアクセスできるようにし、alice という名前のユーザーが HTTP 経由で HTTPBin アプリケーションにアクセスできないようにします。

    kubectl exec deployment/httpbin -c istio-proxy -- curl asm-opa:8181/v1/policies/policy/policy.rego -XPUT --data-binary 'package asm.authz
    
    import future.keywords
    import input.attributes.request.http as http_request
    import input.parsed_path
    
    default allow := false
    
    allow if {
      parsed_path[0] == "health"
    }
    
    allow if {
      http_request.method == "HEAD"
    }
    
    allow if {
      user_name == "bob" // ユーザー bob のみを許可します
    }
    
    user_name := parsed if {
      [_, encoded] := split(http_request.headers.authorization, " ")
      [parsed, _] := split(base64url.decode(encoded), ":")
    }'
  2. bob という名前のユーザーを使用して、次のコマンドを実行して HTTPBin アプリケーションにアクセスします。

    curl ${IP address of the ASM gateway}/status/201 -I -X GET --user bob:testpassword

    予期される出力:

    HTTP/1.1 201 Created
    server: istio-envoy
    date: Tue, 25 Jul 2023 08:32:16 GMT
    content-type: text/html; charset=utf-8
    access-control-allow-origin: *
    access-control-allow-credentials: true
    content-length: 0
    x-envoy-upstream-service-time: 3

    出力は、ユーザー bob のアクセスが成功したことを示しています。

  3. alice という名前のユーザーを使用して、次のコマンドを実行して HTTPBin アプリケーションにアクセスします。

    curl ${IP address of the ASM gateway}/status/201 -I -X GET --user alice:testpassword

    予期される出力:

    HTTP/1.1 403 Forbidden
    date: Tue, 25 Jul 2023 08:32:49 GMT
    server: istio-envoy
    content-length: 0
    x-envoy-upstream-service-time: 1

    出力は、ユーザー alice のアクセスが禁止されていることを示しています。