To better secure the ingress gateway, you need to obtain the originating IP address of a client. This way, you can create an authorization policy to restrict requests to the ingress gateway by specifying the IP address blacklist and whitelist. This topic describes how to obtain the originating IP address of a client.

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. Connect to ACK clusters by using kubectl.
    2. Deploy the 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.
    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
    3. On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
    4. On the details page of the ASM instance, click ASM Gateways in the left-side navigation pane. On the ASM Gateways page, click Create.
    5. Configure the basic information of the ingress gateway service. The following table describes the major parameters. You can use the default settings for other parameters.
      Parameter Description
      Name The name of the ingress gateway service.
      Cluster The cluster in which you want to deploy the ingress gateway service.
      Gateway types The type of the gateway service. Set the value to North-South IngressGateway.
      SLB Instance Type The access type of the SLB instance that you want to use. Set the value to Internet Access.
      Create SLB Instance or Use Existing SLB Instance The SLB instance that you want to use. You can select an SLB instance by using one of the following methods:
      • Use Existing SLB Instance: Select an existing SLB instance from the drop-down list.
      • Create SLB Instance: Click Create SLB Instance and select an SLB instance type from the drop-down list.
      Port Mapping The port mappings. Click Add Port. In the row that appears, select the protocol type and specify a service port.
    6. 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 an ASM instance.
    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 Deploy an ingress gateway service.
  5. Add the IP address of the ingress gateway that you obtain in the preceding substep to WAF. For more information, see Tutorials.
  6. Add the numTrustedProxies parameter to the ingress gateway.
    1. Log on to the ASM console.
    2. In the left-side navigation pane, choose Service Mesh > Mesh Management.
    3. On the Mesh Management page, find the ASM instance that you want to configure. Click the name of the ASM instance or click Manage in the Actions column.
    4. On the details page of the ASM instance, click ASM Gateways in the left-side navigation pane.
    5. On the ASM Gateways page, find the ingress gateway to which you want to add a parameter and click View YAML in the Actions column.
    6. 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.