All Products
Search
Document Center

Alibaba Cloud Service Mesh:Enable ASM gateway to obtain client IP by configuring XFF request header

Last Updated:Mar 11, 2026

When requests pass through proxies, load balancers, or CDN nodes before reaching your ASM gateway, the gateway sees the last proxy's IP instead of the client's originating IP address. Configure the gateway to extract the originating address from the X-Forwarded-For (XFF) header so that access control policies, compliance audits, and anti-fraud systems can identify the real client.

ASM supports two extraction methods. Choose based on your network topology:

TopologyMethodConfiguration fieldWhen to use
Fixed number of proxiesTrusted hop countnumTrustedProxiesAll requests pass through the same proxy chain
Variable number of proxiesTrusted CIDR allowlistxffTrustedCidrsDifferent clients may traverse different proxy paths
Important

This feature requires ASM version 1.24.6.83 or later. Upgrade your ASM instance if needed.

How XFF works

X-Forwarded-For is an HTTP request header that records IP addresses as a request passes through proxy servers, load balancers, or Alibaba Cloud CDN nodes. Each hop appends the previous hop's IP to the header:

X-Forwarded-For: <originating client IP>, <first proxy IP>, <second proxy IP>, ...

The leftmost address is the client's originating IP. The rightmost addresses belong to proxies closer to the gateway.

Extract client IP by trusted hop count

Use this method when requests always pass through a fixed number of proxies before reaching the gateway.

How it works

The gateway counts backward from the end of the XFF list by the number of trusted hops and treats the next address as the client IP.

Example: Three proxies sit between the client and the gateway. Set numTrustedProxies to 2 (number of proxies in the chain minus 1).

Trusted proxy hop count topology diagram

After the request passes through all three proxies, the XFF header contains:

X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3

The gateway skips the last 2 addresses (3.3.3.3, 2.2.2.2) and identifies 1.1.1.1 as the client's originating IP.

Configure the trusted hop count

Warning

This operation triggers a rolling restart of the gateway. Perform it during off-peak hours.

  1. Open the ASM gateway resource for editing using the ASM kubeconfig:

       kubectl -n istio-system edit istiogateway <ASM gateway name>
  2. Add the numTrustedProxies annotation to the gateway pod: Replace <number of proxies in the chain minus 1> with the actual value. For example, with 3 proxies, set this to 2.

       spec:
         podAnnotations:
           proxy.istio.io/config: |
             gatewayTopology:
               numTrustedProxies: <number of proxies in the chain minus 1>
  3. Save and close the file. The configuration takes effect after the gateway pod restarts.

Verify the configuration

After the gateway pod restarts, send a test request with a synthetic XFF header and check the gateway access log:

# Send a request with a simulated XFF header
curl -H 'X-Forwarded-For: 56.5.6.7, 72.9.5.6, 98.1.2.3' http://<gateway-address>/<path>

In the gateway access log, confirm that the extracted client IP matches the expected originating address (56.5.6.7 in this example).

Usage notes

  • The value of numTrustedProxies must be less than the total number of IP addresses in the XFF header. If it equals or exceeds the count, the gateway falls back to using the rightmost address in the XFF list as the client IP.

    Warning

    Setting numTrustedProxies higher than the actual number of proxies allows an attacker to spoof a trusted client IP by injecting extra entries into the XFF header. Always set this value to match your actual proxy chain length.

  • The XFF header recorded in the ASM gateway access log includes an additional address appended by the gateway itself. This appending happens after the numTrustedProxies calculation. For example, if Proxy3's IP is 4.4.4.4, the access log shows: This does not affect the accuracy of the extracted client IP.

      X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3, 4.4.4.4

Extract client IP by trusted CIDR allowlist

Use this method when requests pass through a variable number of proxies, making a fixed hop count unreliable.

How it works

Instead of counting hops, the gateway walks the XFF list from right to left and skips any address that matches a trusted CIDR range. The first non-matching address is treated as the client IP.

Example: Client1 connects through Proxy1 and Proxy3, while Client2 connects through Proxy2, Proxy4, and Proxy3. The hop count differs between the two paths, so numTrustedProxies alone cannot extract the correct client IP.

Variable topology with trusted CIDR allowlist diagram

Add the IPs of Proxy1 through Proxy4 to the trusted CIDR allowlist. The gateway skips these known proxy addresses and correctly identifies each client's originating IP.

Configure the trusted CIDR allowlist

Warning

This operation triggers a rolling restart of the gateway. Perform it during off-peak hours.

  1. Open the ASM gateway resource for editing using the ASM kubeconfig:

       kubectl -n istio-system edit istiogateway <ASM gateway name>
  2. Add the xffTrustedCidrs annotation to the gateway pod with all known proxy IPs in CIDR notation: Replace the CIDR values with your actual proxy IP addresses. Individual IPs require the /32 suffix.

       spec:
         podAnnotations:
           proxy.istio.io/config: |
             gatewayTopology:
               xffTrustedCidrs:
               - 2.2.2.2/32
               - 3.3.3.3/32
               - 4.4.4.4/32
               - 5.5.5.5/32
  3. Save and close the file. The configuration takes effect after the gateway pod restarts.

Verify the configuration

After the gateway pod restarts, send test requests with different XFF headers that simulate each client path and check the gateway access log to confirm the correct client IP is extracted.

# Simulate Client1's path (through Proxy1 and Proxy3)
curl -H 'X-Forwarded-For: 1.1.1.1, 2.2.2.2, 4.4.4.4' http://<gateway-address>/<path>

# Simulate Client2's path (through Proxy2, Proxy4, and Proxy3)
curl -H 'X-Forwarded-For: 6.6.6.6, 3.3.3.3, 5.5.5.5, 4.4.4.4' http://<gateway-address>/<path>

In the gateway access log, confirm that the extracted client IP is 1.1.1.1 for the first request and 6.6.6.6 for the second request.

Usage notes

  • Only CIDR notation is accepted. Specify individual IPs with a /32 suffix (for example, 2.2.2.2/32).

  • Add all known proxy and load balancer IPs to the allowlist. Missing entries cause the gateway to misidentify a proxy IP as the client IP.

Configuration reference

FieldDescriptionFormatScope
numTrustedProxiesNumber of trusted proxy hops to skip when extracting the client IP from the XFF header. Set to the total number of proxies in the chain minus 1.IntegerPer-gateway (pod annotation)
xffTrustedCidrsList of CIDR ranges for known proxy IPs. The gateway skips matching addresses when walking the XFF list from right to left.CIDR list (e.g., 2.2.2.2/32)Per-gateway (pod annotation)
proxy.istio.io/configIstio proxy configuration annotation key under spec.podAnnotations.YAML stringPer-gateway (pod annotation)
gatewayTopologyConfiguration block within proxy.istio.io/config that contains XFF-related settings.YAML objectPer-gateway (pod annotation)

Related topics