全部產品
Search
文件中心

Alibaba Cloud Service Mesh:在HTTP要求標頭中擷取用戶端真實IP

更新時間:Jul 30, 2024

為了對ASM的入口網關進行訪問保護,需要擷取用戶端真實IP,以便使用授權原則設定訪問入口網關的IP黑名單和白名單。本文介紹如何在HTTP要求標頭中擷取用戶端真實IP。

前提條件

背景資訊

通常情況下,應用程式依靠反向 Proxy來轉寄請求中的用戶端屬性,例如X-Forwarded-For標題。但是由於Istio可以部署多種網路拓撲,除了直接使用負載平衡器CLB的公網地址訪問之外,也可能會在Web應用程式防火牆(WAF)接入入口網關地址,或者使用其他的未指定的部署拓撲來訪問入口網關地址。在支援各種部署架構的情況下,Service MeshASM無法提供一個固定的預設值,將用戶端屬性正確轉寄到目標工作負載,也就無法直接通過X-Forwarded-For擷取用戶端真實IP。

為瞭解決上述問題,您需要在ASM網關中將numTrustedProxies參數的值,配置為部署在網關代理前面的可受信的代理數量,以便正確擷取用戶端地址。控制入口網關在X-Envoy-External-Address標題中填充的值,以便上遊服務使用該值來訪問用戶端的原始IP地址。

操作步驟

  1. 部署樣本應用。

    1. 通過kubectl管理叢集和應用。具體操作,請參見擷取叢集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: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/httpbin:0.1.0
                imagePullPolicy: IfNotPresent
                name: httpbin
                ports:
                - containerPort: 80
                                                
      2. 執行以下命令,部署httpbin應用。

        kubectl apply -f httpbin.yaml
  2. 建立ASM網關。

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

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇ASM網關 > 入口網關

    3. 入口網關頁面,單擊建立,配置網關的基本資料。

      負載平衡CLB類型選擇公網訪問,其他按需配置即可。關於配置項的更多資訊,請參見建立入口網關服務

    4. 單擊進階選項,設定外部流量策略Local,然後單擊建立

  3. 建立網關規則和虛擬服務。

    1. 通過API方式管理ASM執行個體。具體操作,請參見通過控制面kubectl訪問Istio資源

    2. 建立網關規則。

      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. 執行以下命令,建立網關規則。

        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. 擷取httpbin應用的80連接埠的入口網關地址。具體操作,請參見建立入口網關服務

  5. Web Application Firewall,接入步驟4擷取的入口網關的地址。具體操作,請參見使用教程

  6. 為ASM網關添加numTrustedProxies參數。

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

    2. 網格管理頁面,單擊目標執行個體名稱,然後在左側導覽列,選擇ASM網關 > 入口網關

    3. 入口網關頁面的目標網關右側,單擊查看YAML

    4. 編輯對話方塊的spec參數下,添加以下內容,然後單擊確定

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

      根據實際的拓撲設定numTrustedProxies為部署在網關代理前面的可受信的代理數量。如果設定numTrustedProxies為一個大於零的值N,則可信用戶端地址為X-Forwarded-For右側起的第N+1個地址。

  7. 執行以下命令,訪問httpbin應用,擷取用戶端真實IP。

    curl http://{入口網關地址}/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。