Configuring Gateway Network Topology [experimental]
Configuring network topologies
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:
spec:
meshConfig:
defaultConfig:
gatewayTopology:
numTrustedProxies: <VALUE>
forwardClientCertDetails: <ENUM_VALUE>
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.
...
metadata:
annotations:
"proxy.istio.io/config": '{"gatewayTopology" : { "numTrustedProxies": <VALUE>, "forwardClientCertDetails": <ENUM_VALUE> } }'
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
.
Example using X-Forwarded-For capability with httpbin
Run the following command to create a file named
topology.yaml
withnumTrustedProxies
set to2
and install Istio:$ cat <<EOF > topology.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: meshConfig: defaultConfig: gatewayTopology: numTrustedProxies: 2 EOF $ istioctl install -f topology.yaml
Create an
httpbin
namespace:$ kubectl create namespace httpbin namespace/httpbin created
Set the
istio-injection
label toenabled
for sidecar injection:$ kubectl label --overwrite namespace httpbin istio-injection=enabled namespace/httpbin labeled
Deploy
httpbin
in thehttpbin
namespace:$ kubectl apply -n httpbin -f samples/httpbin/httpbin.yaml
Deploy a gateway associated with
httpbin
:$ kubectl apply -n httpbin -f samples/httpbin/httpbin-gateway.yaml
Set a local
GATEWAY_URL
environmental variable based on your Istio ingress gateway’s IP address:$ export GATEWAY_URL=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
Run the following
curl
command to simulate a request with proxy addresses in theX-Forwarded-For
header:$ 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, <YOUR GATEWAY IP>", ... }, ... }
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:
To configure how XFCC headers are handled, set forwardClientCertDetails
in your IstioOperator
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
defaultConfig:
gatewayTopology:
forwardClientCertDetails: <ENUM_VALUE>
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 request’s 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:
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
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.