diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index f8a3ee6a812..51343e7b7b5 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -66,6 +66,10 @@ type ClientTrafficPolicySpec struct { // // +optional EnableProxyProtocol *bool `json:"enableProxyProtocol,omitempty"` + // ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. + // + // +optional + ClientIPDetection *ClientIPDetectionSettings `json:"clientIPDetection,omitempty"` // HTTP3 provides HTTP/3 configuration on the listener. // // +optional @@ -84,6 +88,25 @@ type ClientTrafficPolicySpec struct { HTTP1 *HTTP1Settings `json:"http1,omitempty"` } +// ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. +type ClientIPDetectionSettings struct { + // XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address. + // + // +optional + XForwardedFor *XForwardedForSettings `json:"xForwardedFor,omitempty"` +} + +// XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address. +type XForwardedForSettings struct { + // NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP + // headers to trust when determining the origin client's IP address. + // Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for + // for more details. + // + // +optional + NumTrustedHops *uint32 `json:"numTrustedHops,omitempty"` +} + // HTTP3Settings provides HTTP/3 configuration on the listener. type HTTP3Settings struct { } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 45ae918b520..3e20c07e25a 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -347,6 +347,26 @@ func (in *ClaimToHeader) DeepCopy() *ClaimToHeader { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientIPDetectionSettings) DeepCopyInto(out *ClientIPDetectionSettings) { + *out = *in + if in.XForwardedFor != nil { + in, out := &in.XForwardedFor, &out.XForwardedFor + *out = new(XForwardedForSettings) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientIPDetectionSettings. +func (in *ClientIPDetectionSettings) DeepCopy() *ClientIPDetectionSettings { + if in == nil { + return nil + } + out := new(ClientIPDetectionSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClientTrafficPolicy) DeepCopyInto(out *ClientTrafficPolicy) { *out = *in @@ -425,6 +445,11 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) { *out = new(bool) **out = **in } + if in.ClientIPDetection != nil { + in, out := &in.ClientIPDetection, &out.ClientIPDetection + *out = new(ClientIPDetectionSettings) + (*in).DeepCopyInto(*out) + } if in.HTTP3 != nil { in, out := &in.HTTP3, &out.HTTP3 *out = new(HTTP3Settings) @@ -3182,3 +3207,23 @@ func (in *XDSTranslatorHooks) DeepCopy() *XDSTranslatorHooks { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XForwardedForSettings) DeepCopyInto(out *XForwardedForSettings) { + *out = *in + if in.NumTrustedHops != nil { + in, out := &in.NumTrustedHops, &out.NumTrustedHops + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XForwardedForSettings. +func (in *XForwardedForSettings) DeepCopy() *XForwardedForSettings { + if in == nil { + return nil + } + out := new(XForwardedForSettings) + in.DeepCopyInto(out) + return out +} diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index 6f52be525fc..decac13240f 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -44,6 +44,25 @@ spec: spec: description: Spec defines the desired state of ClientTrafficPolicy. properties: + clientIPDetection: + description: ClientIPDetectionSettings provides configuration for + determining the original client IP address for requests. + properties: + xForwardedFor: + description: XForwardedForSettings provides configuration for + using X-Forwarded-For headers for determining the client IP + address. + properties: + numTrustedHops: + description: NumTrustedHops controls the number of additional + ingress proxy hops from the right side of XFF HTTP headers + to trust when determining the origin client's IP address. + Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for + for more details. + format: int32 + type: integer + type: object + type: object enableProxyProtocol: description: EnableProxyProtocol interprets the ProxyProtocol header and adds the Client Address into the X-Forwarded-For header. Note diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 0ee2c28a4a3..4f794a080c1 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -292,6 +292,9 @@ func (t *Translator) translateClientTrafficPolicyForListener(policySpec *egv1a1. // Translate Proxy Protocol translateListenerProxyProtocol(policySpec.EnableProxyProtocol, httpIR) + // Translate Client IP Detection + translateClientIPDetection(policySpec.ClientIPDetection, httpIR) + // Translate Suppress Envoy Headers translateListenerSuppressEnvoyHeaders(policySpec.SuppressEnvoyHeaders, httpIR) @@ -375,6 +378,15 @@ func translateListenerProxyProtocol(enableProxyProtocol *bool, httpIR *ir.HTTPLi } } +func translateClientIPDetection(clientIPDetection *egv1a1.ClientIPDetectionSettings, httpIR *ir.HTTPListener) { + // Return early if not set + if clientIPDetection == nil { + return + } + + httpIR.ClientIPDetection = (*ir.ClientIPDetectionSettings)(clientIPDetection) +} + func translateListenerSuppressEnvoyHeaders(suppressEnvoyHeaders *bool, httpIR *ir.HTTPListener) { if suppressEnvoyHeaders != nil { httpIR.SuppressEnvoyHeaders = *suppressEnvoyHeaders diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml new file mode 100644 index 00000000000..b2505cfa8de --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml @@ -0,0 +1,30 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1 + spec: + clientIPDetection: + xForwardedFor: + numTrustedHops: 2 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-1 + protocol: HTTP + port: 8081 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml new file mode 100644 index 00000000000..fc9a18e1f40 --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml @@ -0,0 +1,98 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1 + namespace: envoy-gateway + spec: + clientIPDetection: + xForwardedFor: + numTrustedHops: 2 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + status: + conditions: + - lastTransitionTime: null + message: ClientTrafficPolicy has been accepted. + reason: Accepted + status: "True" + type: Accepted +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http-1 + port: 8081 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http-1 + ports: + - containerPort: 8081 + name: http-1 + protocol: HTTP + servicePort: 8081 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + clientIPDetection: + xForwardedFor: + numTrustedHops: 2 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8081 diff --git a/internal/ir/xds.go b/internal/ir/xds.go index d06bb0ce000..2fcb00928f3 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -214,6 +214,8 @@ type HTTPListener struct { SuppressEnvoyHeaders bool `json:"suppressEnvoyHeaders,omitempty" yaml:"suppressEnvoyHeaders,omitempty"` // EnableProxyProtocol enables the listener to interpret proxy protocol header EnableProxyProtocol bool `json:"enableProxyProtocol,omitempty" yaml:"enableProxyProtocol,omitempty"` + // ClientIPDetection controls how the original client IP address is determined for requests. + ClientIPDetection *ClientIPDetectionSettings `json:"clientIPDetection,omitempty" yaml:"clientIPDetection,omitempty"` // HTTP3 provides HTTP/3 configuration on the listener. // +optional HTTP3 *HTTP3Settings `json:"http3,omitempty"` @@ -340,6 +342,10 @@ type PathSettings struct { EscapedSlashesAction PathEscapedSlashAction `json:"escapedSlashesAction" yaml:"escapedSlashesAction"` } +// ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. +// +k8s:deepcopy-gen=true +type ClientIPDetectionSettings egv1a1.ClientIPDetectionSettings + // BackendWeights stores the weights of valid and invalid backends for the route so that 500 error responses can be returned in the same proportions type BackendWeights struct { Valid uint32 `json:"valid" yaml:"valid"` diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 882c6b125f0..fa6739bebae 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -178,6 +178,26 @@ func (in *CircuitBreaker) DeepCopy() *CircuitBreaker { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientIPDetectionSettings) DeepCopyInto(out *ClientIPDetectionSettings) { + *out = *in + if in.XForwardedFor != nil { + in, out := &in.XForwardedFor, &out.XForwardedFor + *out = new(v1alpha1.XForwardedForSettings) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientIPDetectionSettings. +func (in *ClientIPDetectionSettings) DeepCopy() *ClientIPDetectionSettings { + if in == nil { + return nil + } + out := new(ClientIPDetectionSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ConsistentHash) DeepCopyInto(out *ConsistentHash) { *out = *in @@ -496,6 +516,11 @@ func (in *HTTPListener) DeepCopyInto(out *HTTPListener) { *out = new(TCPKeepalive) (*in).DeepCopyInto(*out) } + if in.ClientIPDetection != nil { + in, out := &in.ClientIPDetection, &out.ClientIPDetection + *out = new(ClientIPDetectionSettings) + (*in).DeepCopyInto(*out) + } if in.HTTP3 != nil { in, out := &in.HTTP3, &out.HTTP3 *out = new(HTTP3Settings) diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index efd1a272fd7..6d2e9da6d0d 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -24,6 +24,7 @@ import ( "github.com/golang/protobuf/ptypes/wrappers" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/wrapperspb" + "k8s.io/utils/ptr" "github.com/envoyproxy/gateway/internal/ir" "github.com/envoyproxy/gateway/internal/utils/protocov" @@ -146,6 +147,13 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL } else { statPrefix = "http" } + + // Client IP detection + var xffNumTrustedHops uint32 + if irListener.ClientIPDetection != nil && irListener.ClientIPDetection.XForwardedFor != nil { + xffNumTrustedHops = ptr.Deref(irListener.ClientIPDetection.XForwardedFor.NumTrustedHops, 0) + } + mgr := &hcmv3.HttpConnectionManager{ AccessLog: al, CodecType: hcmv3.HttpConnectionManager_AUTO, @@ -162,7 +170,8 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL // Set it by default to also support HTTP1.1 to HTTP2 Upgrades Http2ProtocolOptions: http2ProtocolOptions(), // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for - UseRemoteAddress: &wrappers.BoolValue{Value: true}, + UseRemoteAddress: &wrappers.BoolValue{Value: true}, + XffNumTrustedHops: xffNumTrustedHops, // normalize paths according to RFC 3986 NormalizePath: &wrapperspb.BoolValue{Value: true}, MergeSlashes: irListener.Path.MergeSlashes, diff --git a/internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml b/internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml new file mode 100644 index 00000000000..f12c1c129f5 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml @@ -0,0 +1,18 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 8081 + hostnames: + - "*" + routes: + - name: "first-route" + hostname: "*" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.1.1.1" + port: 8081 + clientIPDetection: + xForwardedFor: + numTrustedHops: 2 diff --git a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.clusters.yaml new file mode 100755 index 00000000000..c8692b81602 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.clusters.yaml @@ -0,0 +1,14 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + lbPolicy: LEAST_REQUEST + name: first-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.endpoints.yaml new file mode 100755 index 00000000000..79a52664410 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.1.1.1 + portValue: 8081 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.listeners.yaml new file mode 100755 index 00000000000..19c18f54b11 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.listeners.yaml @@ -0,0 +1,32 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 8081 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + normalizePath: true + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + statPrefix: http + upgradeConfigs: + - upgradeType: websocket + useRemoteAddress: true + xffNumTrustedHops: 2 + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.routes.yaml new file mode 100755 index 00000000000..2734c7cc42a --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/client-ip-detection.routes.yaml @@ -0,0 +1,12 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + prefix: / + name: first-route + route: + cluster: first-route-dest diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index 7e200d848cd..6ea8bc483e9 100644 --- a/internal/xds/translator/translator_test.go +++ b/internal/xds/translator/translator_test.go @@ -237,6 +237,9 @@ func TestTranslateXds(t *testing.T) { { name: "path-settings", }, + { + name: "client-ip-detection", + }, { name: "http1-trailers", }, diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 479ef575af1..8c3069268f1 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -231,6 +231,20 @@ _Appears in:_ | `claim` | _string_ | true | Claim is the JWT Claim that should be saved into the header : it can be a nested claim of type (eg. "claim.nested.key", "sub"). The nested claim name must use dot "." to separate the JSON name path. | +#### ClientIPDetectionSettings + + + +ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. + +_Appears in:_ +- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `xForwardedFor` | _[XForwardedForSettings](#xforwardedforsettings)_ | false | XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address. | + + #### ClientTrafficPolicy @@ -279,6 +293,7 @@ _Appears in:_ | `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the downstream client connection. If defined, sets SO_KEEPALIVE on the listener socket to enable TCP Keepalives. Disabled by default. | | `suppressEnvoyHeaders` | _boolean_ | false | SuppressEnvoyHeaders configures the Envoy Router filter to suppress the "x-envoy-' headers from both requests and responses. By default these headers are added to both requests and responses. | | `enableProxyProtocol` | _boolean_ | false | EnableProxyProtocol interprets the ProxyProtocol header and adds the Client Address into the X-Forwarded-For header. Note Proxy Protocol must be present when this field is set, else the connection is closed. | +| `clientIPDetection` | _[ClientIPDetectionSettings](#clientipdetectionsettings)_ | false | ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. | | `http3` | _[HTTP3Settings](#http3settings)_ | false | HTTP3 provides HTTP/3 configuration on the listener. | | `tls` | _[TLSSettings](#tlssettings)_ | false | TLS settings configure TLS termination settings with the downstream client. | | `path` | _[PathSettings](#pathsettings)_ | false | Path enables managing how the incoming path set by clients can be normalized. | @@ -2305,3 +2320,17 @@ _Appears in:_ | `post` | _[XDSTranslatorHook](#xdstranslatorhook) array_ | true | | +#### XForwardedForSettings + + + +XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address. + +_Appears in:_ +- [ClientIPDetectionSettings](#clientipdetectionsettings) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for for more details. | + + diff --git a/site/content/en/latest/user/client-traffic-policy.md b/site/content/en/latest/user/client-traffic-policy.md index 9d89a0eb816..c6766b8cd5f 100644 --- a/site/content/en/latest/user/client-traffic-policy.md +++ b/site/content/en/latest/user/client-traffic-policy.md @@ -285,5 +285,130 @@ You should now expect 200 response status and also see that source IP was preser } ``` +### Configure Client IP Detection + +This example configures the number of additional ingress proxy hops from the right side of XFF HTTP headers to trust when determining the origin client's IP address and determines whether or not `x-forwarded-proto` headers will be trusted. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for for details. + +```shell +cat < GET /get HTTP/1.1 +> Host: www.example.com +> User-Agent: curl/8.4.0 +> Accept: */* +> X-Forwarded-Proto: https +> X-Forwarded-For: 1.1.1.1,2.2.2.2 +> +Handling connection for 8888 +< HTTP/1.1 200 OK +< content-type: application/json +< x-content-type-options: nosniff +< date: Tue, 30 Jan 2024 15:19:22 GMT +< content-length: 535 +< x-envoy-upstream-service-time: 0 +< server: envoy +< +{ + "path": "/get", + "host": "www.example.com", + "method": "GET", + "proto": "HTTP/1.1", + "headers": { + "Accept": [ + "*/*" + ], + "User-Agent": [ + "curl/8.4.0" + ], + "X-Envoy-Expected-Rq-Timeout-Ms": [ + "15000" + ], + "X-Envoy-External-Address": [ + "1.1.1.1" + ], + "X-Forwarded-For": [ + "1.1.1.1,2.2.2.2,10.244.0.9" + ], + "X-Forwarded-Proto": [ + "https" + ], + "X-Request-Id": [ + "53ccfad7-1899-40fa-9322-ddb833aa1ac3" + ] + }, + "namespace": "default", + "ingress": "", + "service": "", + "pod": "backend-58d58f745-8psnc" +* Connection #0 to host localhost left intact +} +``` + [ClientTrafficPolicy]: ../../api/extension_types#clienttrafficpolicy [BackendTrafficPolicy]: ../../api/extension_types#backendtrafficpolicy