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

Alibaba Cloud Service Mesh:HTTP プロトコルを使用したカスタム認証の実装

最終更新日:Jan 14, 2025

カスタム認証機能を使用すると、HTTP プロトコルを使用するサービスに対してきめ細かいリソースアクセス管理 (RAM) を実行できます。この機能を使用すると、ビジネス要件に基づいて認証メカニズムをカスタマイズできます。サービスが相互に通信する場合、認証が必要です。これにより、認証および承認されたリクエストのみが特定のサービスリソースにアクセスできるようになり、サービス間の通信のセキュリティが向上します。このトピックでは、次の例で httpbin アプリケーションと sleep アプリケーションを使用して、HTTP プロトコルを使用したカスタム認証の実装方法について説明します。

前提条件

コンテナサービス Kubernetes 版 (ACK) クラスタがサービスメッシュ (ASM) インスタンスに追加されています。詳細については、「ASM インスタンスへのクラスタの追加」をご参照ください。

ステップ 1: カスタム認証サービスをデプロイする

ACK クラスタにカスタム認証サービスをデプロイします。このサービスは、カスタム認証サービスの Istio の API 仕様に準拠し、HTTP プロトコルと gRPC プロトコルをサポートしている必要があります。このサービスは、カスタム認証を実装するために使用されます。このトピックで提供されているサンプル認証サービスでは、x-ext-authz: allow ヘッダーを持つリクエストのみが認証を通過できると指定されています。

説明

次のサンプル認証サービスを使用するか、サンプル認証サービスのコードに基づいてカスタム認証サービスを作成できます。詳細については、GitHub の Web サイトをご覧ください。

  1. kubectl を使用してクラスターに接続し、次の内容を使用して ext-authz.yaml ファイルを作成します。

    kubectl を使用してクラスターに接続する方法の詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。

    [ext-authz.yaml ファイルを表示するには展開します]

    # Istio Authors による著作権
    #
    #   Apache License, Version 2.0(以下「ライセンス」)に基づいてライセンスされています。
    #   ライセンスに準拠する場合を除き、このファイルを使用することはできません。
    #   ライセンスのコピーは、次の場所で取得できます。
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   適用法で要求されている場合、または書面で合意されている場合を除き、ソフトウェア
    #   ライセンスに基づいて配布されるものは、「現状有姿」で配布され、
    #   明示または黙示を問わず、いかなる種類の保証も条件もありません。
    #   ライセンスに基づく権限と制限を規定する特定の言語については、ライセンスを参照してください。
    
    # メッシュに個別に ext-authz サーバーをデプロイするための設定例。
    
    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 apply -f ext-authz.yaml
  3. カスタム承認サービスが存在するポッドのステータスをクエリするには、次のコマンドを実行します。

    kubectl get pod

    予想される出力:

    NAME                         READY   STATUS    RESTARTS   AGE
    ext-authz-6b5db88f86-2m7c6   2/2     Running   0          79m
  4. 次のコマンドを実行して、ext-authz アプリケーションが想定どおりに動作するかどうかを確認します。

    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

    上記の戻り値が返された場合、カスタム承認サービスがデプロイされています。

  5. ext-authz サービスで使用されている HTTP ポートを取得します。

    1. ACK コンソール にログインします。左側のナビゲーションペインで、[クラスター] をクリックします。

    2. [クラスター] ページで、管理するクラスターを見つけ、その名前をクリックします。左側のペインで、[ネットワーク] > [サービス] を選択します。

    3. [サービス] ページで、[ext-authz] をクリックします。

      サービス詳細ページの [エンドポイント] セクションで、HTTP ポートを表示できます。この例では、ポートは 8000 です。カスタム認証サービスへのアクセスに使用する HTTP アドレスは ext-authz.default.svc.cluster.local:8000 です。

手順 2: サンプル アプリケーションをデプロイする

  1. 次の内容を含む httpbin.yaml ファイルを作成します。

    展開して httpbin.yaml ファイルを表示する

    # Istio Authors の著作権
    #
    #   Apache ライセンス バージョン 2.0(以下「ライセンス」)に基づいてライセンスされています。
    #   ライセンスに準拠する場合を除き、このファイルを使用することはできません。
    #   ライセンスのコピーは以下から取得できます。
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   適用法で要求されている場合、または書面で合意されている場合を除き、ソフトウェア
    #   ライセンスに基づいて配布されるものは「現状有姿」で配布され、
    #   明示または黙示を問わず、いかなる種類の保証も条件も提供されません。
    #   ライセンスに基づく権限と制限を規定する特定の言語については、ライセンスを参照してください。
    
    ##################################################################################################
    # httpbin サービス
    ##################################################################################################
    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 ファイルを表示する

    # Istio Authors の著作権
    #
    #   Apache ライセンス バージョン 2.0(以下「ライセンス」)に基づいてライセンスされています。
    #   ライセンスに準拠する場合を除き、このファイルを使用することはできません。
    #   ライセンスのコピーは以下から取得できます。
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   適用法で要求されている場合、または書面で合意されている場合を除き、ソフトウェア
    #   ライセンスに基づいて配布されるものは「現状有姿」で配布され、
    #   明示または黙示を問わず、いかなる種類の保証も条件も提供されません。
    #   ライセンスに基づく権限と制限を規定する特定の言語については、ライセンスを参照してください。
    
    ##################################################################################################
    # Sleep サービス
    ##################################################################################################
    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

ステップ 3:HTTP プロトコルを使用してカスタム認証サービスに接続する

ステップ 1 でデプロイしたカスタム認証サービスを ASM インスタンスで宣言します。このようにして、ASM インスタンスはサービスを使用してリクエストを認証できます。

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

  2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、[メッシュセキュリティセンター] > [カスタム認証サービス] を選択します。表示されるページで、[カスタム認証サービスの定義] をクリックします。

  3. [カスタム認証サービスの登録] ページで、[envoy.ext_authz に基づいて実装されたカスタム認証サービス (HTTP または Grpc プロトコル)] タブをクリックし、関連パラメータを設定して、[作成] をクリックします。

    タイプ

    パラメータ

    説明

    必須パラメータ

    プロトコル

    カスタム認証サービスで使用されるプロトコル。この例では、HTTP が選択されています。

    名前

    カスタム認証サービスの名前。この例では、値は test4http に設定されています。

    サービスアドレス

    カスタム認証サービスのエンドポイント。形式は <サービス名>.<名前空間>.svc.<クラスタのドメイン名> です。名前は完全名である必要があります。この例では、値は ext-authz.default.svc.cluster.local に設定されています。

    ポート (1 ~ 65535)

    カスタム認証サービスのサービスポート。この例では、値は 8000 に設定されています。

    タイムアウト (秒)

    認証結果が返される必要がある期間。単位:秒。カスタム認証アプリケーションがこの期間内に応答に失敗した場合、サービスは使用不可と見なされます。この例では、値は 10 に設定されています。

    オプション パラメーター

    認証サービスが利用できない場合に認証をスキップする

    カスタム認証サービスが利用できない場合にリクエストを許可するかどうかを指定します。このスイッチをオンにすると、カスタム認証サービスが利用できない場合にリクエストが許可されます。この例では、スイッチはオフになっています。

    認証サービスが利用できない場合に ASM プロキシによって返されるエラーコード

    カスタム認証サービスが利用できない場合に返すエラーコード。このパラメーターは、[認証サービスが利用できない場合に認証をスキップ] をオフにした場合にのみ使用できます。[認証サービスが利用できない場合に ASM プロキシによって返されるエラーコード] をオンにした場合は、エラーコードを指定する必要があります。このようにして、カスタム認証サービスが利用できない場合、ASM はこのエラーコードを呼び出し元に返します。この例では、スイッチはオフになっています。

    認証リクエスト内でオリジンヘッダーを伝達する

    カスタム認証サービスに送信される認証リクエストに、指定されたクライアントリクエストヘッダーを含めるかどうかを指定します。このスイッチをオンにした場合は、1 つ以上のヘッダーキーを指定する必要があります。指定されたヘッダーがクライアントリクエストで見つかった場合、ASM はそれらをカスタム認証サービスに送信される認証リクエストに追加します。この例のこれらの設定は、認証リクエストでのヘッダーの伝達に示されています。

    説明

    このパラメーターは、[プロトコル] パラメーターを HTTP に設定した場合にのみ使用できます。

    認証リクエストにヘッダーを追加する

    カスタム認証サービスに送信される認証リクエストに追加のヘッダーを含めるかどうかを指定します。このスイッチをオンにした場合は、1 つ以上のヘッダーキーと値を指定する必要があります。指定すると、ASM はカスタム認証サービスに送信される認証リクエストにヘッダーキーと値を追加します。

    同じヘッダーキーを持つヘッダーがクライアントリクエストに既に存在する場合、元のヘッダー値は上書きされます。この例では、スイッチはオフになっています。

    説明

    このパラメーターは、[プロトコル] パラメーターを HTTP に設定した場合にのみ使用できます。

    認証成功時にヘッダーを上書き

    認証が成功した場合、アップストリームに送信されるクライアントリクエストで指定されたヘッダーを上書きするかどうかを指定します。このスイッチをオンにする場合は、1 つ以上のヘッダーキーを指定する必要があります。認証が成功した場合、ASM はクライアントリクエストで指定されたヘッダーを、認証レスポンスで返されたヘッダーで上書きします。この例の認証成功時にヘッダーを上書きに設定が示されています。

    説明

    このパラメーターは、プロトコル パラメーターを HTTP に設定した場合にのみ使用できます。

    認証に失敗した場合にヘッダーを上書きする

    認証に失敗した場合に、呼び出し元に送信されるレスポンスで指定されたヘッダーを上書きするかどうかを指定します。このスイッチをオンにする場合は、1 つ以上のヘッダーキーを指定する必要があります。認証に失敗した場合、ASM は呼び出し元に送信されるレスポンスのヘッダーを、認証レスポンスで指定されたヘッダーで上書きします。この例の認証失敗時のヘッダーの上書きの設定を示します。

    説明

    このパラメーターは、[プロトコル] パラメーターを [HTTP] に設定した場合にのみ使用できます。

    認証リクエスト内で元のリクエスト本文を伝達する

    カスタム認証サービスに送信される認証リクエストにクライアントリクエスト本文を含めるかどうかを指定します。このスイッチをオンにする場合は、リクエスト本文の最大長を指定する必要があります。[不完全なメッセージを認証サービスに送信することを許可する] もオンにした場合、リクエスト本文の長さが最大値を超えると、ASM はリクエスト本文を切り捨てます。そして、ASM は切り捨てられたリクエスト本文を含む認証リクエストをカスタム認証サービスに送信します。

    図 1. 認証リクエスト内でヘッダーを伝送する

    説明

    最後の行 x-ext-authz は、リクエストに追加された新しいヘッダーです。

    在鉴权请求中携带Header

    図 2. 認証が成功した場合にヘッダーを上書きする

    説明

    最後の行 x-ext-authz-check-result は、リクエストに追加された新しいヘッダーです。

    鉴权通过时覆盖Header

    図 3. 認証失敗時のヘッダーの上書き

    説明

    最後の行 x-ext-authz-check-result は、リクエストに追加された新しいヘッダーです。

    鉴权失败时覆盖Header

ステップ 4:ASM インスタンスの承認ポリシーを作成する

認証が必要なリクエスト操作を設定するために、承認ポリシーを作成します。

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

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

  3. [作成] ページで、関連パラメーターを設定し、[作成] をクリックします。

    パラメーター

    説明

    名前

    カスタム承認ポリシーの名前。この例では、値は test1 に設定されています。

    ポリシータイプ

    カスタム承認ポリシーのタイプ。この例では、値は カスタム承認サービス に設定されています。

    カスタム承認サービス

    この例では、httpextauth-test4http(HTTP) が選択されています。

    名前空間

    承認ポリシーが存在する名前空間。[ワークロードスコープ] タブで、名前空間ドロップダウンリストから default を選択します。

    有効範囲

    承認ポリシーの有効範囲。この例では、値は サービス に設定されています。

    ワークロード

    承認ポリシーが有効になるワークロード。この例では、値は httpbin に設定されています。

    リクエスト一致ルール

    リクエストの宛先パス。この例では、[リクエストターゲットの追加] セクションで パス がオンになっており、値は /headers に設定されています。

ステップ 5: カスタム承認サービスが有効になっていることを確認する

  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 が返されます。これは、カスタム承認がトリガーされていないことを示します。その理由は、パスに承認ポリシーで定義されている /headers ではなく /ip が含まれているためです。

  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 -i

    予想される出力:

    HTTP/1.1 403 Forbidden
    x-ext-authz-check-result: denied
    content-length: 76
    content-type: text/plain; charset=utf-8
    date: Wed, 20 Dec 2023 09:53:28 GMT
    server: envoy
    x-envoy-upstream-service-time: 10
    
    denied by ext_authz for not found header `x-ext-authz: allow` in the request

    上記の結果は、カスタム承認がトリガーされたものの、認証が失敗したことを示しています。返された結果には、新しく追加されたレスポンスヘッダー x-ext-authz-check-result: denied が含まれています。承認がトリガーされた理由は、パスに承認ポリシーで定義されている /headers が含まれているためです。

  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"
      }
    }

    上記の結果は、カスタム承認がトリガーされ、認証が成功したことを示しています。返された結果には、新しく追加されたレスポンスヘッダー "X-Ext-Authz-Check-Result": "allowed" が含まれています。承認がトリガーされた理由は、パスに承認ポリシーで定義されている /headers が含まれているためです。

参照資料