Skip to content

Commit 2856c19

Browse files
committed
Add ClientTrafficPolicy XFF append disable support
Signed-off-by: Alexander Bolshakov <lextiz@gmail.com>
1 parent 9cac348 commit 2856c19

18 files changed

Lines changed: 229 additions & 6 deletions

api/v1alpha1/clienttrafficpolicy_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ type HeaderSettings struct {
139139
// +optional
140140
DisableRateLimitHeaders *bool `json:"disableRateLimitHeaders,omitempty"`
141141

142+
// DisableXForwardedFor configures Envoy Proxy to stop appending the downstream address
143+
// to the X-Forwarded-For header.
144+
//
145+
// This only disables the automatic append behavior. It does not remove or sanitize
146+
// an incoming X-Forwarded-For header.
147+
// +optional
148+
DisableXForwardedFor *bool `json:"disableXForwardedFor,omitempty"`
149+
142150
// XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
143151
//
144152
// x-forwarded-client-cert (XFCC) is an HTTP header used to forward the certificate

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ spec:
237237
DisableRateLimitHeaders configures Envoy Proxy to omit the "X-RateLimit-" response headers
238238
when rate limiting is enabled.
239239
type: boolean
240+
disableXForwardedFor:
241+
description: |-
242+
DisableXForwardedFor configures Envoy Proxy to stop appending the downstream address
243+
to the X-Forwarded-For header.
244+
245+
This only disables the automatic append behavior. It does not remove or sanitize
246+
an incoming X-Forwarded-For header.
247+
type: boolean
240248
earlyRequestHeaders:
241249
description: |-
242250
EarlyRequestHeaders defines settings for early request header modification, before envoy performs

charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,14 @@ spec:
236236
DisableRateLimitHeaders configures Envoy Proxy to omit the "X-RateLimit-" response headers
237237
when rate limiting is enabled.
238238
type: boolean
239+
disableXForwardedFor:
240+
description: |-
241+
DisableXForwardedFor configures Envoy Proxy to stop appending the downstream address
242+
to the X-Forwarded-For header.
243+
244+
This only disables the automatic append behavior. It does not remove or sanitize
245+
an incoming X-Forwarded-For header.
246+
type: boolean
239247
earlyRequestHeaders:
240248
description: |-
241249
EarlyRequestHeaders defines settings for early request header modification, before envoy performs

internal/gatewayapi/clienttrafficpolicy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, http
672672
httpIR.Headers = &ir.HeaderSettings{
673673
EnableEnvoyHeaders: ptr.Deref(headerSettings.EnableEnvoyHeaders, false),
674674
DisableRateLimitHeaders: ptr.Deref(headerSettings.DisableRateLimitHeaders, false),
675+
DisableXForwardedFor: ptr.Deref(headerSettings.DisableXForwardedFor, false),
675676
WithUnderscoresAction: ir.WithUnderscoresAction(ptr.Deref(headerSettings.WithUnderscoresAction, egv1a1.WithUnderscoresActionRejectRequest)),
676677
}
677678
if headerSettings.RequestID != nil {

internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.in.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ clientTrafficPolicies:
88
clientIPDetection:
99
xForwardedFor:
1010
numTrustedHops: 2
11+
headers:
12+
disableXForwardedFor: true
1113
targetRef:
1214
group: gateway.networking.k8s.io
1315
kind: Gateway
@@ -43,6 +45,19 @@ clientTrafficPolicies:
4345
kind: Gateway
4446
name: gateway-1
4547
sectionName: http-3
48+
- apiVersion: gateway.envoyproxy.io/v1alpha1
49+
kind: ClientTrafficPolicy
50+
metadata:
51+
namespace: envoy-gateway
52+
name: target-gateway-1-http-4
53+
spec:
54+
headers:
55+
disableXForwardedFor: true
56+
targetRef:
57+
group: gateway.networking.k8s.io
58+
kind: Gateway
59+
name: gateway-1
60+
sectionName: http-4
4661
gateways:
4762
- apiVersion: gateway.networking.k8s.io/v1
4863
kind: Gateway

internal/gatewayapi/testdata/clienttrafficpolicy-client-ip-detection.out.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ clientTrafficPolicies:
88
clientIPDetection:
99
xForwardedFor:
1010
numTrustedHops: 2
11+
headers:
12+
disableXForwardedFor: true
1113
targetRef:
1214
group: gateway.networking.k8s.io
1315
kind: Gateway
@@ -88,6 +90,34 @@ clientTrafficPolicies:
8890
status: "True"
8991
type: Accepted
9092
controllerName: gateway.envoyproxy.io/gatewayclass-controller
93+
- apiVersion: gateway.envoyproxy.io/v1alpha1
94+
kind: ClientTrafficPolicy
95+
metadata:
96+
name: target-gateway-1-http-4
97+
namespace: envoy-gateway
98+
spec:
99+
headers:
100+
disableXForwardedFor: true
101+
targetRef:
102+
group: gateway.networking.k8s.io
103+
kind: Gateway
104+
name: gateway-1
105+
sectionName: http-4
106+
status:
107+
ancestors:
108+
- ancestorRef:
109+
group: gateway.networking.k8s.io
110+
kind: Gateway
111+
name: gateway-1
112+
namespace: envoy-gateway
113+
sectionName: http-4
114+
conditions:
115+
- lastTransitionTime: null
116+
message: Policy has been accepted.
117+
reason: Accepted
118+
status: "True"
119+
type: Accepted
120+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
91121
gateways:
92122
- apiVersion: gateway.networking.k8s.io/v1
93123
kind: Gateway
@@ -283,6 +313,9 @@ xdsIR:
283313
clientIPDetection:
284314
xForwardedFor:
285315
numTrustedHops: 2
316+
headers:
317+
disableXForwardedFor: true
318+
withUnderscoresAction: RejectRequest
286319
externalPort: 8081
287320
hostnames:
288321
- '*'
@@ -334,6 +367,9 @@ xdsIR:
334367
port: 8083
335368
- address: 0.0.0.0
336369
externalPort: 8084
370+
headers:
371+
disableXForwardedFor: true
372+
withUnderscoresAction: RejectRequest
337373
hostnames:
338374
- '*'
339375
metadata:

internal/ir/xds.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,10 @@ type HeaderSettings struct {
777777
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ratelimit/v3/rate_limit.proto#extensions-filters-http-ratelimit-v3-ratelimit
778778
DisableRateLimitHeaders bool `json:"disableRateLimitHeaders,omitempty" yaml:"disableRateLimitHeaders,omitempty"`
779779

780+
// DisableXForwardedFor controls if Envoy should stop appending the downstream address to
781+
// the X-Forwarded-For header. The default is to keep appending the downstream address.
782+
DisableXForwardedFor bool `json:"disableXForwardedFor,omitempty" yaml:"disableXForwardedFor,omitempty"`
783+
780784
// Configure Envoy proxy how to handle the x-forwarded-client-cert (XFCC) HTTP header.
781785
// refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-enum-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-forwardclientcertdetails
782786
XForwardedClientCert *XForwardedClientCert `json:"xForwardedClientCert,omitempty" yaml:"xForwardedClientCert,omitempty"`

internal/xds/translator/listener.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func xffNumTrustedHops(clientIPDetection *ir.ClientIPDetectionSettings) uint32 {
141141
return 0
142142
}
143143

144-
func originalIPDetectionExtensions(clientIPDetection *ir.ClientIPDetectionSettings) []*corev3.TypedExtensionConfig {
144+
func originalIPDetectionExtensions(clientIPDetection *ir.ClientIPDetectionSettings, headers *ir.HeaderSettings) []*corev3.TypedExtensionConfig {
145145
// Return early if settings are nil
146146
if clientIPDetection == nil {
147147
return nil
@@ -183,12 +183,12 @@ func originalIPDetectionExtensions(clientIPDetection *ir.ClientIPDetectionSettin
183183
XffTrustedCidrs: &xffv3.XffTrustedCidrs{
184184
Cidrs: trustedCidrs,
185185
},
186-
SkipXffAppend: wrapperspb.Bool(false),
186+
SkipXffAppend: wrapperspb.Bool(headers != nil && headers.DisableXForwardedFor),
187187
})
188188
} else if clientIPDetection.XForwardedFor.NumTrustedHops != nil {
189189
xffHeaderConfigAny, _ = proto.ToAnyWithValidation(&xffv3.XffConfig{
190190
XffNumTrustedHops: xffNumTrustedHops(clientIPDetection),
191-
SkipXffAppend: wrapperspb.Bool(false),
191+
SkipXffAppend: wrapperspb.Bool(headers != nil && headers.DisableXForwardedFor),
192192
})
193193
}
194194
extensionConfig = append(extensionConfig, &corev3.TypedExtensionConfig{
@@ -354,7 +354,7 @@ func (t *Translator) addHCMToXDSListener(
354354
// HTTP filter configuration
355355
// Client IP detection
356356
useRemoteAddress := true
357-
originalIPDetectionExtensions := originalIPDetectionExtensions(irListener.ClientIPDetection)
357+
originalIPDetectionExtensions := originalIPDetectionExtensions(irListener.ClientIPDetection, irListener.Headers)
358358
if originalIPDetectionExtensions != nil {
359359
useRemoteAddress = false
360360
}
@@ -378,6 +378,7 @@ func (t *Translator) addHCMToXDSListener(
378378
Http2ProtocolOptions: http2ProtocolOptions(irListener.HTTP2),
379379
// https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
380380
UseRemoteAddress: &wrapperspb.BoolValue{Value: useRemoteAddress},
381+
SkipXffAppend: ptr.Deref(irListener.Headers, ir.HeaderSettings{}).DisableXForwardedFor,
381382
OriginalIpDetectionExtensions: originalIPDetectionExtensions,
382383
// normalize paths according to RFC 3986
383384
NormalizePath: &wrapperspb.BoolValue{Value: true},

internal/xds/translator/testdata/in/xds-ir/client-ip-detection.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ http:
1717
clientIPDetection:
1818
xForwardedFor:
1919
numTrustedHops: 2
20+
headers:
21+
disableXForwardedFor: true
2022
- name: "second-listener"
2123
address: "::"
2224
port: 8082
@@ -76,3 +78,21 @@ http:
7678
- "192.168.1.0/24"
7779
- "10.0.0.0/16"
7880
- "172.16.0.0/12"
81+
82+
- name: "fifth-listener"
83+
address: "::"
84+
port: 8085
85+
hostnames:
86+
- "*"
87+
headers:
88+
disableXForwardedFor: true
89+
routes:
90+
- name: "fifth-route"
91+
hostname: "*"
92+
destination:
93+
name: "fifth-route-dest"
94+
settings:
95+
- endpoints:
96+
- host: "5.5.5.5"
97+
port: 8085
98+
name: "fifth-route-dest/backend/0"

0 commit comments

Comments
 (0)