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

Alibaba Cloud Service Mesh:HTTP リクエストヘッダーからクライアントの発信元 IP アドレスを取得する

最終更新日:Jan 13, 2025

イングレスゲートウェイで IP ベースのアクセス制御を実施するには、クライアントの発信元 IP アドレスを取得する必要があります。たとえば、IP アドレスのブラックリストまたはホワイトリストを構成することで、イングレスゲートウェイへのリクエストを拒否または許可する承認ポリシーを作成できます。このトピックでは、HTTP リクエストヘッダーからクライアントの発信元 IP アドレスを取得する方法について説明します。

前提条件

背景情報

ほとんどの場合、クライアントの属性を含むリクエストは、リバースプロキシを使用してアプリケーションに転送されます。たとえば、リクエストには X-Forwarded-For ヘッダーが含まれています。Istio では、さまざまなネットワークトポロジをデプロイできます。イングレスゲートウェイの IP アドレスにアクセスするには、クラシックロードバランサー(CLB)インスタンスのパブリック IP アドレスを使用するか、イングレスゲートウェイの IP アドレスを Web アプリケーションファイアウォール(WAF)に追加するか、不特定のネットワークトポロジを使用できます。この場合、クライアント属性を含むリクエストが指定されたワークロードに転送される場合、X-Forwarded-For ヘッダーの発信元 IP アドレスを識別するために固定のデフォルト値を使用することはできません。したがって、X-Forwarded-For リクエストヘッダーの値に基づいてクライアントの発信元 IP アドレスを取得することはできません。

この問題を解決するには、numTrustedProxies パラメーターを、イングレスゲートウェイの前にデプロイされている信頼できるプロキシの数に設定します。イングレスゲートウェイは、numTrustedProxies パラメーターの値に基づいてクライアントの発信元 IP アドレスを取得し、X-Envoy-External-Address ヘッダーの値を設定します。この場合、アップストリームサービスは、X-Envoy-External-Address ヘッダーの値に基づいてクライアントの発信元 IP アドレスにアクセスできます。

手順

  1. サンプルアプリケーションをデプロイします。

    1. kubectl を使用して Container Service for Kubernetes(ACK)クラスターに接続します。詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。

    2. HTTPBin アプリケーションをデプロイします。

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

        httpbin.yaml ファイルを表示

        # 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
  2. イングレスゲートウェイを作成します。

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

    2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、[ASM ゲートウェイ] > [イングレスゲートウェイ] を選択します。

    3. [イングレスゲートウェイ] ページで、[作成] をクリックします。作成ページで、イングレスゲートウェイに必要なパラメーターを構成します。

      [CLB インスタンスタイプ][インターネットアクセス] に設定します。パラメーターの詳細については、「イングレスゲートウェイを作成する」をご参照ください。

    4. [詳細オプション] をクリックし、[外部トラフィックポリシー][ローカル] に設定して、[作成] をクリックします。

  3. Istio ゲートウェイと仮想サービスを作成します。

    1. kubectl を使用して ASM インスタンスに接続し、API 操作を呼び出してインスタンスを管理できるようにします。詳細については、「コントロールプレーンで kubectl を使用して Istio リソースにアクセスする」をご参照ください。

    2. Istio ゲートウェイを作成します。

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

        apiVersion: networking.istio.io/v1alpha3
        kind: Gateway
        metadata:
          name: httpbin-gateway
        spec:
          selector:
            istio: ingressgateway
          servers:
          - port:
              number: 80
              name: http
              protocol: HTTP
            hosts:
            - "*"
      2. 次のコマンドを実行して、Istio ゲートウェイを作成します。

        kubectl apply -f httpbin-gateway.yaml
    3. 仮想サービスを作成します。

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

        apiVersion: networking.istio.io/v1alpha3
        kind: VirtualService
        metadata:
          name: httpbin
        spec:
          hosts:
          - "*"
          gateways:
          - httpbin-gateway
          http:
          - route:
            - destination:
                host: httpbin
                port:
                  number: 8000
      2. 次のコマンドを実行して、仮想サービスを作成します。

        kubectl apply -f httpbin-virtualservice.yaml
  4. ポート番号が 80 のイングレスゲートウェイの IP アドレスを取得します。詳細については、「イングレスゲートウェイを作成する」をご参照ください。

  5. 手順 4 で取得したイングレスゲートウェイの IP アドレスを WAF に追加します。詳細については、「チュートリアル」をご参照ください。

  6. numTrustedProxies パラメーターをイングレスゲートウェイに追加します。

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

    2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、[ASM ゲートウェイ] > [イングレスゲートウェイ] を選択します。

    3. [イングレスゲートウェイ] ページで、イングレスゲートウェイを見つけて [YAML] をクリックします。

    4. [編集] ダイアログボックスで、次の内容を spec パラメーターに追加し、[OK] をクリックします。

      podAnnotations:
          proxy.istio.io/config: '{"gatewayTopology" : { "numTrustedProxies": 2 } }'

      numTrustedProxies パラメーターは、ネットワークトポロジに基づいて、イングレスゲートウェイの前にデプロイされている信頼できるプロキシの数に設定します。numTrustedProxies パラメーターを 0 より大きい値 N に設定すると、信頼できるクライアントの発信元 IP アドレスは、X-Forwarded-For パラメーターの値の(N + 1)番目のアドレスになります。

  7. 次のコマンドを実行して HTTPBin アプリケーションにアクセスし、クライアントの発信元 IP アドレスを取得します。

    curl http://{イングレスゲートウェイの IP アドレス}/get?show_env=true

    予期される出力:

    {
      "args": {
        "show_env": "true"
      },
      "headers": {
        "Accept": "*/*",
        ....
        "X-Envoy-Attempt-Count": "1",
        "X-Envoy-External-Address": "106.11.**.**",
        ....
      },
      ....
    }

    X-Envoy-External-Address パラメーターの値は、クライアントの発信元 IP アドレスです。