istio.io/content/en/docs/ops/configuration/traffic-management/network-topologies/index.md

9.3 KiB
Raw Blame History

title description weight keywords owner test
Configuring Gateway Network Topology [Experimental] How to configure gateway network topology (experimental). 60
traffic-management
ingress
gateway
istio/wg-networking-maintainers no

Configuring network topologies

{{< boilerplate experimental >}}

Istio provides the ability to manage settings like X-Forwarded-For (XFF) and X-Forwarded-Client-Cert (XFCC), which are dependent on how the gateway workloads are deployed. This is currently an in-development feature. For more information on X-Forwarded-For, see the IETF's RFC.

You might choose to deploy Istio ingress gateways in various network topologies (e.g. behind Cloud Load Balancers, a self-managed Load Balancer or directly expose the Istio ingress gateway to the Internet). As such, these topologies require different ingress gateway configurations for transporting correct client attributes like IP addresses and certificates to the workloads running in the cluster.

Configuration of XFF and XFCC headers can be set globally for all gateway workloads via MeshConfig or per gateway using a pod annotation. For example, to configure globally during install or upgrade when using an IstioOperator custom resource:

{{< text yaml >}} spec: meshConfig: defaultConfig: gatewayTopology: numTrustedProxies: forwardClientCertDetails: <ENUM_VALUE> {{< /text >}}

You can also configure both of these settings by adding the proxy.istio.io/config annotation to the Pod spec of your Istio ingress gateway.

{{< text yaml >}} ... metadata: annotations: "proxy.istio.io/config": '{"gatewayTopology" : { "numTrustedProxies": , "forwardClientCertDetails": <ENUM_VALUE> } }' {{< /text >}}

Configuring X-Forwarded-For Headers

Applications rely on reverse proxies to forward client attributes in a request, such as X-Forward-For header. However, due to the variety of network topologies that Istio can be deployed in, you must set the numTrustedProxies to the number of trusted proxies deployed in front of the Istio gateway proxy, so that the client address can be extracted correctly. This controls the value populated by the ingress gateway in the X-Envoy-External-Address header which can be reliably used by the upstream services to access client's original IP address.

For example, if you have a cloud based Load Balancer and a reverse proxy in front of your Istio gateway, set numTrustedProxies to 2.

{{< idea >}} Note that all proxies in front of the Istio gateway proxy must parse HTTP traffic and append to the X-Forwarded-For header at each hop. If the number of entries in the X-Forwarded-For header is less than the number of trusted hops configured, Envoy falls back to using the immediate downstream address as the trusted client address. Please refer to the Envoy documentation to understand how X-Forwarded-For headers and trusted client addresses are determined. {{< /idea >}}

Example using X-Forwarded-For capability with httpbin

  1. Run the following command to create a file named topology.yaml with numTrustedProxies set to 2 and install Istio:

    {{< text bash >}} $ cat < topology.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: meshConfig: defaultConfig: gatewayTopology: numTrustedProxies: 2 EOF $ istioctl install -f topology.yaml {{< /text >}}

    {{< idea >}} If you previously installed an Istio ingress gateway, restart all ingress gateway pods after step 1. {{</ idea >}}

  2. Create an httpbin namespace:

    {{< text bash >}} $ kubectl create namespace httpbin namespace/httpbin created {{< /text >}}

  3. Set the istio-injection label to enabled for sidecar injection:

    {{< text bash >}} $ kubectl label --overwrite namespace httpbin istio-injection=enabled namespace/httpbin labeled {{< /text >}}

  4. Deploy httpbin in the httpbin namespace:

    {{< text bash >}} $ kubectl apply -n httpbin -f samples/httpbin/httpbin.yaml {{< /text >}}

  5. Deploy a gateway associated with httpbin:

    {{< text bash >}} $ kubectl apply -n httpbin -f samples/httpbin/httpbin-gateway.yaml {{< /text >}}

  6. Set a local GATEWAY_URL environmental variable based on your Istio ingress gateway's IP address:

    {{< text bash >}} export GATEWAY_URL=(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}') {{< /text >}}

  7. Run the following curl command to simulate a request with proxy addresses in the X-Forwarded-For header:

    {{< text bash >}} $ curl -H 'X-Forwarded-For: 56.5.6.7, 72.9.5.6, 98.1.2.3' $GATEWAY_URL/get?show_env=true { "args": { "show_env": "true" }, "headers": { ... "X-Envoy-External-Address": "72.9.5.6", ... "X-Forwarded-For": "56.5.6.7, 72.9.5.6, 98.1.2.3, ", ... }, ... } {{< /text >}}

The above output shows the request headers that the httpbin workload received. When the Istio gateway received this request, it set the X-Envoy-External-Address header to the second to last (numTrustedProxies: 2) address in the X-Forwarded-For header from your curl command. Additionally, the gateway appends its own IP to the X-Forwarded-For header before forwarding it to the httpbin workload.

Configuring X-Forwarded-Client-Cert Headers

From Envoy's documentation regarding XFCC:

{{< quote >}} x-forwarded-client-cert (XFCC) is a proxy header which indicates certificate information of part or all of the clients or proxies that a request has flowed through, on its way from the client to the server. A proxy may choose to sanitize/append/forward the XFCC header before proxying the request. {{< /quote >}}

To configure how XFCC headers are handled, set forwardClientCertDetails in your IstioOperator

{{< text yaml >}} apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: meshConfig: defaultConfig: gatewayTopology: forwardClientCertDetails: <ENUM_VALUE> {{< /text >}}

where ENUM_VALUE can be of the following type.

ENUM_VALUE
UNDEFINED Field is not set.
SANITIZE Do not send the XFCC header to the next hop. This is the default value for a gateway.
FORWARD_ONLY When the client connection is mTLS (Mutual TLS), forward the XFCC header in the request.
APPEND_FORWARD When the client connection is mTLS, append the client certificate information to the requests XFCC header and forward it.
SANITIZE_SET When the client connection is mTLS, reset the XFCC header with the client certificate information and send it to the next hop.
ALWAYS_FORWARD_ONLY Always forward the XFCC header in the request, regardless of whether the client connection is mTLS.

See the Envoy documentation for examples of using this capability.

PROXY Protocol

The PROXY protocol allows for exchanging and preservation of client attributes across multiple proxies without relying on Layer 7 protocols.

If your external load balancer is configured to use the PROXY protocol, the Istio gateway must also be configured accept PROXY protocol. Enabling this requires adding Envoy Proxy Protocol filter using an EnvoyFilter applied on the gateway workload. For example:

{{< text yaml >}} apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: proxy-protocol namespace: istio-system spec: configPatches:

  • applyTo: LISTENER patch: operation: MERGE value: listener_filters: - name: envoy.listener.proxy_protocol - name: envoy.listener.tls_inspector workloadSelector: labels: istio: ingressgateway {{< /text >}}

The client IP is retrieved from the PROXY protocol and set (or appended) in the X-Forwarded-For and X-Envoy-External-Address header. When PROXY protocol is used in conjunction with the gatewayTopology configuration, the numTrustedProxies and the received X-Forwarded-For header takes precedence in determining the trusted client addresses.