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-Forward-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 Server Load Balancer (SLB) 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 an httpbin application.
      1. Create an httpbin.yaml file that contains the following content:
        # 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 page that appears, configure the parameters.
      The following table describes the parameters that you must configure. Retain the default values for other parameters. For more information about the parameters, see Create an ingress gateway service.
      ParameterDescription
      NameThe name of the ingress gateway.
      ClusterThe cluster in which you want to deploy the ingress gateway.
      SLB Instance TypeThe access type of the SLB instance. Set the value to Internet Access.
      Create SLB Instance or Use Existing SLB InstanceThe SLB instance that you want to use. You can use an existing SLB instance or create an SLB instance:
      • Use Existing SLB Instance: Select an existing SLB instance from the drop-down list.
      • Create SLB Instance: Select a specification from the drop-down list for the SLB instance that you want to create.
      Port MappingSpecify the ports that services need to expose. You can click Add Port and specify a service port and protocol in the row that appears.
    4. Click Advanced Options, set the External Traffic Policy parameter 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 service.
  5. Add the IP address of the ingress gateway that you obtain in the preceding substep to WAF.4 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-Forward-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.