From a91f771e71a50055fb2d1c1e40e95c7e00c958bd Mon Sep 17 00:00:00 2001 From: David Alger Date: Mon, 29 Jan 2024 15:06:32 -0600 Subject: [PATCH] feat: HTTPConnectionManager settings for XFF headers on ClientTrafficPolicy (#2252) Signed-off-by: David Alger --- api/v1alpha1/clienttrafficpolicy_types.go | 22 +++ api/v1alpha1/zz_generated.deepcopy.go | 30 ++++ ...y.envoyproxy.io_clienttrafficpolicies.yaml | 20 +++ internal/gatewayapi/clienttrafficpolicy.go | 13 ++ ...y-http-connection-manager-settings.in.yaml | 37 +++++ ...-http-connection-manager-settings.out.yaml | 143 ++++++++++++++++++ internal/ir/xds.go | 10 ++ internal/ir/zz_generated.deepcopy.go | 5 + internal/xds/translator/listener.go | 13 +- .../http-connection-manager-settings.yaml | 31 ++++ ...-connection-manager-settings.clusters.yaml | 28 ++++ ...connection-manager-settings.endpoints.yaml | 24 +++ ...connection-manager-settings.listeners.yaml | 63 ++++++++ ...tp-connection-manager-settings.routes.yaml | 24 +++ internal/xds/translator/translator_test.go | 3 + site/content/en/latest/api/extension_types.md | 16 ++ .../en/latest/user/client-traffic-policy.md | 57 +++++++ 17 files changed, 538 insertions(+), 1 deletion(-) create mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.in.yaml create mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.out.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/http-connection-manager-settings.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.routes.yaml diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index f8a3ee6a812d..9696a4fb6fb0 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"` + // HTTPConnectionManager provides HTTP Connection Manager configuration on the listener. + // + // +optional + HTTPConnectionManager *HTTPConnectionManagerSettings `json:"httpConnectionManager,omitempty"` // HTTP3 provides HTTP/3 configuration on the listener. // // +optional @@ -84,6 +88,24 @@ type ClientTrafficPolicySpec struct { HTTP1 *HTTP1Settings `json:"http1,omitempty"` } +// HTTPConnectionManagerSettings provides HTTP Connection Manager configuration on the listener. +type HTTPConnectionManagerSettings struct { + // UseRemoteAddress controls whether the connection manager will use the real remote address of the + // client connection when determining internal versus external origin and manipulating various headers. + // Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for + // Enabled by default. + // + // +optional + // +kubebuilder:default=true + UseRemoteAddress *bool `json:"useRemoteAddress,omitempty"` + // XffNumTrustedHops 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 + // + // +optional + XffNumTrustedHops *uint32 `json:"xffNumTrustedHops,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 fb28e8369318..e2c560f4f22c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -350,6 +350,11 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) { *out = new(bool) **out = **in } + if in.HTTPConnectionManager != nil { + in, out := &in.HTTPConnectionManager, &out.HTTPConnectionManager + *out = new(HTTPConnectionManagerSettings) + (*in).DeepCopyInto(*out) + } if in.HTTP3 != nil { in, out := &in.HTTP3, &out.HTTP3 *out = new(HTTP3Settings) @@ -1488,6 +1493,31 @@ func (in *HTTP3Settings) DeepCopy() *HTTP3Settings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPConnectionManagerSettings) DeepCopyInto(out *HTTPConnectionManagerSettings) { + *out = *in + if in.UseRemoteAddress != nil { + in, out := &in.UseRemoteAddress, &out.UseRemoteAddress + *out = new(bool) + **out = **in + } + if in.XffNumTrustedHops != nil { + in, out := &in.XffNumTrustedHops, &out.XffNumTrustedHops + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPConnectionManagerSettings. +func (in *HTTPConnectionManagerSettings) DeepCopy() *HTTPConnectionManagerSettings { + if in == nil { + return nil + } + out := new(HTTPConnectionManagerSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPHealthChecker) DeepCopyInto(out *HTTPHealthChecker) { *out = *in 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 6f52be525fc8..c7f561983a7f 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -66,6 +66,26 @@ spec: http3: description: HTTP3 provides HTTP/3 configuration on the listener. type: object + httpConnectionManager: + description: HTTPConnectionManager provides HTTP Connection Manager + configuration on the listener. + properties: + useRemoteAddress: + default: true + description: UseRemoteAddress controls whether the connection + manager will use the real remote address of the client connection + when determining internal versus external origin and manipulating + various headers. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for + Enabled by default. + type: boolean + xffNumTrustedHops: + description: XffNumTrustedHops 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 + format: int32 + type: integer + type: object path: description: Path enables managing how the incoming path set by clients can be normalized. diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 0ee2c28a4a32..d1319ab0a08e 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 HTTP Connection Manager + translateHTTPConnectionManager(policySpec.HTTPConnectionManager, httpIR) + // Translate Suppress Envoy Headers translateListenerSuppressEnvoyHeaders(policySpec.SuppressEnvoyHeaders, httpIR) @@ -375,6 +378,16 @@ func translateListenerProxyProtocol(enableProxyProtocol *bool, httpIR *ir.HTTPLi } } +func translateHTTPConnectionManager(httpConnectionManager *egv1a1.HTTPConnectionManagerSettings, httpIR *ir.HTTPListener) { + // Return early if not set + if httpConnectionManager == nil { + return + } + + httpIR.UseRemoteAddress = httpConnectionManager.UseRemoteAddress + httpIR.XffNumTrustedHops = ptr.Deref(httpConnectionManager.XffNumTrustedHops, 0) +} + func translateListenerSuppressEnvoyHeaders(suppressEnvoyHeaders *bool, httpIR *ir.HTTPListener) { if suppressEnvoyHeaders != nil { httpIR.SuppressEnvoyHeaders = *suppressEnvoyHeaders diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.in.yaml new file mode 100644 index 000000000000..190c676a4445 --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.in.yaml @@ -0,0 +1,37 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1 + spec: + httpConnectionManager: + useRemoteAddress: false + xffNumTrustedHops: 2 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 +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: 80 + allowedRoutes: + namespaces: + from: Same + - name: http-2 + protocol: HTTP + port: 8080 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.out.yaml new file mode 100644 index 000000000000..c7e6e71414ff --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http-connection-manager-settings.out.yaml @@ -0,0 +1,143 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + creationTimestamp: null + name: target-gateway-1 + namespace: envoy-gateway + spec: + httpConnectionManager: + useRemoteAddress: false + xffNumTrustedHops: 2 + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + 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: 80 + protocol: HTTP + - allowedRoutes: + namespaces: + from: Same + name: http-2 + port: 8080 + 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 + - 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-2 + 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: 10080 + name: http-1 + protocol: HTTP + servicePort: 80 + - address: null + name: envoy-gateway/gateway-1/http-2 + ports: + - containerPort: 8080 + name: http-2 + protocol: HTTP + servicePort: 8080 + 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 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + useRemoteAddress: false + xffNumTrustedHops: 2 + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: envoy-gateway/gateway-1/http-2 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 8080 diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 65bad668b154..f2c52957da76 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -214,6 +214,14 @@ 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"` + // UseRemoteAddress controls whether the connection manager will use the real remote address of the + // client connection when determining internal versus external origin and manipulating various headers. + // Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for + UseRemoteAddress *bool `json:"useRemoteAddress,omitempty" yaml:"useRemoteAddress,omitempty"` + // XffNumTrustedHops 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 + XffNumTrustedHops uint32 `json:"xffNumTrustedHops,omitempty" yaml:"xffNumTrustedHops,omitempty"` // HTTP3 provides HTTP/3 configuration on the listener. // +optional HTTP3 *HTTP3Settings `json:"http3,omitempty"` @@ -340,6 +348,8 @@ type PathSettings struct { EscapedSlashesAction PathEscapedSlashAction `json:"escapedSlashesAction" yaml:"escapedSlashesAction"` } +type HTTPConnectionManagerSettings egv1a1.HTTPConnectionManagerSettings + // 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 f6b57c02a88c..9ed257ef87e9 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -491,6 +491,11 @@ func (in *HTTPListener) DeepCopyInto(out *HTTPListener) { *out = new(TCPKeepalive) (*in).DeepCopyInto(*out) } + if in.UseRemoteAddress != nil { + in, out := &in.UseRemoteAddress, &out.UseRemoteAddress + *out = new(bool) + **out = **in + } 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 efd1a272fd7b..026aac7ba392 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -146,6 +146,16 @@ func (t *Translator) addXdsHTTPFilterChain(xdsListener *listenerv3.Listener, irL } else { statPrefix = "http" } + + // HTTP XFF configuration + var useRemoteAddress bool + if irListener.UseRemoteAddress != nil { + useRemoteAddress = *irListener.UseRemoteAddress + } else { + // Enable UseRemoteAddress by default when ClientTrafficPolicy is not configured + useRemoteAddress = true + } + mgr := &hcmv3.HttpConnectionManager{ AccessLog: al, CodecType: hcmv3.HttpConnectionManager_AUTO, @@ -162,7 +172,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: useRemoteAddress}, + XffNumTrustedHops: irListener.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/http-connection-manager-settings.yaml b/internal/xds/translator/testdata/in/xds-ir/http-connection-manager-settings.yaml new file mode 100644 index 000000000000..89042f894b28 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http-connection-manager-settings.yaml @@ -0,0 +1,31 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + routes: + - name: "first-route" + hostname: "*" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.1.1.1" + port: 8080 + useRemoteAddress: false + xffNumTrustedHops: 2 +- name: "second-listener" + address: "0.0.0.0" + port: 8080 + hostnames: + - "*" + routes: + - name: "second-route" + hostname: "*" + destination: + name: "second-route-dest" + settings: + - endpoints: + - host: "2.2.2.2" + port: 8080 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.clusters.yaml new file mode 100644 index 000000000000..abfeaa163294 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.clusters.yaml @@ -0,0 +1,28 @@ +- 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 +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: second-route-dest + lbPolicy: LEAST_REQUEST + name: second-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.endpoints.yaml new file mode 100644 index 000000000000..e591a6a83737 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.endpoints.yaml @@ -0,0 +1,24 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.1.1.1 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 +- clusterName: second-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 2.2.2.2 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: second-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.listeners.yaml new file mode 100644 index 000000000000..e8406d1bbdb4 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.listeners.yaml @@ -0,0 +1,63 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + 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: false + xffNumTrustedHops: 2 + name: first-listener + perConnectionBufferLimitBytes: 32768 +- address: + socketAddress: + address: 0.0.0.0 + portValue: 8080 + 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: second-listener + statPrefix: http + upgradeConfigs: + - upgradeType: websocket + useRemoteAddress: true + name: second-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.routes.yaml new file mode 100644 index 000000000000..d36b9824e31c --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-connection-manager-settings.routes.yaml @@ -0,0 +1,24 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + prefix: / + name: first-route + route: + cluster: first-route-dest +- ignorePortInHostMatching: true + name: second-listener + virtualHosts: + - domains: + - '*' + name: second-listener/* + routes: + - match: + prefix: / + name: second-route + route: + cluster: second-route-dest diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index 7e200d848cd7..fedd0db16e82 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: "http-connection-manager-settings", + }, { name: "http1-trailers", }, diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index f29c506c28b6..45a582722c32 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -221,6 +221,7 @@ _Appears in:_ | `tcpKeepalive` _[TCPKeepalive](#tcpkeepalive)_ | 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_ | 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_ | 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. | +| `httpConnectionManager` _[HTTPConnectionManagerSettings](#httpconnectionmanagersettings)_ | HTTPConnectionManager provides HTTP Connection Manager configuration on the listener. | | `http3` _[HTTP3Settings](#http3settings)_ | HTTP3 provides HTTP/3 configuration on the listener. | | `tls` _[TLSSettings](#tlssettings)_ | TLS settings configure TLS termination settings with the downstream client. | | `path` _[PathSettings](#pathsettings)_ | Path enables managing how the incoming path set by clients can be normalized. | @@ -997,6 +998,21 @@ _Appears in:_ +#### HTTPConnectionManagerSettings + + + +HTTPConnectionManagerSettings provides HTTP Connection Manager configuration on the listener. + +_Appears in:_ +- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) + +| Field | Description | +| --- | --- | +| `useRemoteAddress` _boolean_ | UseRemoteAddress controls whether the connection manager will use the real remote address of the client connection when determining internal versus external origin and manipulating various headers. Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for for more details. Defaults to `true`.| +| `xffNumTrustedHops` _boolean_ | XffNumTrustedHops 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. Defaults to 0.| + + #### HTTPHealthChecker diff --git a/site/content/en/latest/user/client-traffic-policy.md b/site/content/en/latest/user/client-traffic-policy.md index 9d89a0eb816b..f803aba6fd67 100644 --- a/site/content/en/latest/user/client-traffic-policy.md +++ b/site/content/en/latest/user/client-traffic-policy.md @@ -285,5 +285,62 @@ You should now expect 200 response status and also see that source IP was preser } ``` +### Configure Number of X-Forwarded-For Trusted Hops + +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 <