All Products
Search
Document Center

Alibaba Cloud Service Mesh:Obtain the originating IP address of a client from the HTTP request header

Last Updated:Feb 01, 2024

To enforce IP-based access control on an ingress gateway, you need to obtain the originating IP address of a client. For example, you can create an authorization policy to deny or allow requests to the ingress gateway by configuring an IP address blacklist or whitelist. This topic describes how to obtain the originating IP address of a client from the HTTP request header.

Prerequisites

Background information

In most cases, requests that contain the attributes of the client are forwarded to applications by using reverse proxies. For example, a request contains the X-Forwarded-For header. Istio allows you to deploy a variety of network topologies. To access the IP address of the ingress gateway, you can use the public IP address of a Classic Load Balancer (CLB) instance, add the IP address of the ingress gateway to Web Application Firewall (WAF), or use an unspecified network topology. In this case, a fixed default value cannot be used to identify the originating IP address in the X-Forwarded-For header if the requests that contain the client attributes are forwarded to a specified workload. Therefore, you cannot obtain the originating IP address of the client based on the value of the X-Forwarded-For request header.

To resolve this issue, you can set the numTrustedProxies parameter to the number of trusted proxies that are deployed prior to the ingress gateway. The ingress gateway obtains the originating IP address of the client based on the value of the numTrustedProxies parameter and sets the value of the X-Envoy-External-Address header. In this case, upstream services can access the originating IP address of the client based on the value of the X-Envoy-External-Address header.

Procedure

  1. Deploy a sample application.

    1. Use kubectl to connect to the Container Service for Kubernetes (ACK) cluster. For more information, see Obtain the kubeconfig file of a cluster and use kubectl to connect to the cluster.

    2. Deploy the HTTPBin application.

      1. Create an httpbin.yaml file that contains the following content:

        Show the httpbin.yaml file

        # 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. Run the following command to deploy the HTTPBin application:

        kubectl apply -f httpbin.yaml
  2. Create an ingress gateway.

    1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.

    3. On the Ingress Gateway page, click Create. On the Create page, configure the required parameters of the ingress gateway.

      Set CLB Instance Type to Internet Access. For more information about the parameters, see Create an ingress gateway.

    4. Click Advanced Options, set External Traffic Policy to Local, and then click Create.

  3. Create an Istio gateway and a virtual service.

    1. Use kubectl to connect to the ASM instance so that you can call API operations to manage the instance. For more information, see Use kubectl on the control plane to access Istio resources.

    2. Create an Istio gateway.

      1. Create an httpbin-gateway.yaml file that contains the following content:

        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. Run the following command to create an Istio gateway:

        kubectl apply -f httpbin-gateway.yaml
    3. Create a virtual service.

      1. Create an httpbin-virtualservice.yaml file that contains the following content:

        apiVersion: networking.istio.io/v1alpha3
        kind: VirtualService
        metadata:
          name: httpbin
        spec:
          hosts:
          - "*"
          gateways:
          - httpbin-gateway
          http:
          - route:
            - destination:
                host: httpbin
                port:
                  number: 8000
      2. Run the following command to create a virtual service:

        kubectl apply -f httpbin-virtualservice.yaml
  4. Obtain the IP address of the ingress gateway whose port number is 80. For more information, see Create an ingress gateway.

  5. Add the IP address of the ingress gateway that you obtain in the substep 4 to WAF. For more information, see Tutorial.

  6. Add the numTrustedProxies parameter to the ingress gateway.

    1. Log on to the ASM console. In the left-side navigation pane, choose Service Mesh > Mesh Management.

    2. On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose ASM Gateways > Ingress Gateway.

    3. On the Ingress Gateway page, find the ingress gateway and click YAML.

    4. In the Edit dialog box, add the following content to the spec parameter, and click OK.

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

      Set the numTrustedProxies parameter to the number of trusted proxies deployed prior to the ingress gateway based on the network topologies. If you set the numTrustedProxies parameter to a value N that is greater than zero, the originating IP address of the trusted client is the (N +1)th address in the value of the X-Forwarded-For parameter.

  7. Run the following command to access the HTTPBin application to obtain the originating IP address of the client:

    curl http://{IP address of the ingress gateway}/get?show_env=true

    Expected output:

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

    The value of the X-Envoy-External-Address parameter is the originating IP address of the client.