Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: support setting trusted CIDRs #4500

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions api/v1alpha1/clienttrafficpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,29 @@ type ClientIPDetectionSettings struct {
}

// XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address.
// Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
// for more details.
// +kubebuilder:validation:XValidation:rule="(has(self.numTrustedHops) && !has(self.trustedCIDRs)) || (!has(self.numTrustedHops) && has(self.trustedCIDRs))", message="only one of numTrustedHops or trustedCIDRs must be set"
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved
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.
// Only one of NumTrustedHops and TrustedCIDRs must be set.
//
// +optional
NumTrustedHops *uint32 `json:"numTrustedHops,omitempty"`

// TrustedCIDRs is a list of CIDR ranges to trust when evaluating
// the remote IP address to determine the original client’s IP address.
// When the remote IP address matches a trusted CIDR and the x-forwarded-for header was sent,
// each entry in the x-forwarded-for header is evaluated from right to left
// and the first public non-trusted address is used as the original client address.
// If all addresses in x-forwarded-for are within the trusted list, the first (leftmost) entry is used.
// Only one of NumTrustedHops and TrustedCIDRs must be set.
//
// +optional
// +kubebuilder:validation:MinItems=1
// +notImplementedHide
TrustedCIDRs []CIDR `json:"trustedCIDRs,omitempty"`
}

// CustomHeaderExtensionSettings provides configuration for determining the client IP address for a request based on
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,32 @@ spec:
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.
Only one of NumTrustedHops and TrustedCIDRs must be set.
format: int32
type: integer
trustedCIDRs:
description: |-
TrustedCIDRs is a list of CIDR ranges to trust when evaluating
the remote IP address to determine the original client’s IP address.
When the remote IP address matches a trusted CIDR and the x-forwarded-for header was sent,
each entry in the x-forwarded-for header is evaluated from right to left
and the first public non-trusted address is used as the original client address.
If all addresses in x-forwarded-for are within the trusted list, the first (leftmost) entry is used.
Only one of NumTrustedHops and TrustedCIDRs must be set.
items:
description: |-
CIDR defines a CIDR Address range.
A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64".
pattern: ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))
type: string
minItems: 1
type: array
type: object
x-kubernetes-validations:
- message: only one of numTrustedHops or trustedCIDRs must be
set
rule: (has(self.numTrustedHops) && !has(self.trustedCIDRs))
|| (!has(self.numTrustedHops) && has(self.trustedCIDRs))
type: object
x-kubernetes-validations:
- message: customHeader cannot be used in conjunction with xForwardedFor
Expand Down
2 changes: 1 addition & 1 deletion release-notes/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ security updates: |

# New features or capabilities added in this release.
new features: |
Add a new feature here
- Added support for trusted CIDRs in the ClientIPDetectionSettings API

# Fixes for bugs identified in previous versions.
bug fixes: |
Expand Down
5 changes: 4 additions & 1 deletion site/content/en/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address

_Appears in:_
- [Principal](#principal)
- [XForwardedForSettings](#xforwardedforsettings)



Expand Down Expand Up @@ -4267,13 +4268,15 @@ _Appears in:_


XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address.
Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
for more details.

_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<br />headers to trust when determining the origin client's IP address.<br />Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for<br />for more details. |
| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP<br />headers to trust when determining the origin client's IP address.<br />Only one of NumTrustedHops and TrustedCIDRs must be set. |


#### ZipkinTracingProvider
Expand Down
5 changes: 4 additions & 1 deletion site/content/zh/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address

_Appears in:_
- [Principal](#principal)
- [XForwardedForSettings](#xforwardedforsettings)



Expand Down Expand Up @@ -4267,13 +4268,15 @@ _Appears in:_


XForwardedForSettings provides configuration for using X-Forwarded-For headers for determining the client IP address.
Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for
for more details.

_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<br />headers to trust when determining the origin client's IP address.<br />Refer to https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-for<br />for more details. |
| `numTrustedHops` | _integer_ | false | NumTrustedHops controls the number of additional ingress proxy hops from the right side of XFF HTTP<br />headers to trust when determining the origin client's IP address.<br />Only one of NumTrustedHops and TrustedCIDRs must be set. |


#### ZipkinTracingProvider
Expand Down
83 changes: 83 additions & 0 deletions test/cel-validation/clienttrafficpolicy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,89 @@ func TestClientTrafficPolicyTarget(t *testing.T) {
"spec.clientIPDetection: Invalid value: \"object\": customHeader cannot be used in conjunction with xForwardedFor",
},
},
{
desc: "clientIPDetection numTrustedHops and trustedCIDRs",
mutate: func(ctp *egv1a1.ClientTrafficPolicy) {
ctp.Spec = egv1a1.ClientTrafficPolicySpec{
PolicyTargetReferences: egv1a1.PolicyTargetReferences{
TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{
LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{
Group: gwapiv1a2.Group("gateway.networking.k8s.io"),
Kind: gwapiv1a2.Kind("Gateway"),
Name: gwapiv1a2.ObjectName("eg"),
},
},
},
ClientIPDetection: &egv1a1.ClientIPDetectionSettings{
XForwardedFor: &egv1a1.XForwardedForSettings{
NumTrustedHops: ptr.To(uint32(1)),
TrustedCIDRs: []egv1a1.CIDR{
"192.168.1.0/24",
"10.0.0.0/16",
"172.16.0.0/12",
},
},
},
}
},
wantErrors: []string{
"spec.clientIPDetection.xForwardedFor: Invalid value: \"object\": only one of numTrustedHops or trustedCIDRs must be set",
},
},
{
desc: "clientIPDetection invalid trustedCIDRs",
mutate: func(ctp *egv1a1.ClientTrafficPolicy) {
ctp.Spec = egv1a1.ClientTrafficPolicySpec{
PolicyTargetReferences: egv1a1.PolicyTargetReferences{
TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{
LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{
Group: gwapiv1a2.Group("gateway.networking.k8s.io"),
Kind: gwapiv1a2.Kind("Gateway"),
Name: gwapiv1a2.ObjectName("eg"),
},
},
},
ClientIPDetection: &egv1a1.ClientIPDetectionSettings{
XForwardedFor: &egv1a1.XForwardedForSettings{
TrustedCIDRs: []egv1a1.CIDR{
"192.0124.1.0/24",
"10.0.0.0/1645",
"17212.16.0.0/123",
},
},
},
}
},
wantErrors: []string{
"spec.clientIPDetection.xForwardedFor.trustedCIDRs[0]: Invalid value: \"192.0124.1.0/24\": spec.clientIPDetection.xForwardedFor.trustedCIDRs[0] in body should match '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/([0-9]+))'",
},
},
{
desc: "clientIPDetection valid trustedCIDRs",
mutate: func(ctp *egv1a1.ClientTrafficPolicy) {
ctp.Spec = egv1a1.ClientTrafficPolicySpec{
PolicyTargetReferences: egv1a1.PolicyTargetReferences{
TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{
LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{
Group: gwapiv1a2.Group("gateway.networking.k8s.io"),
Kind: gwapiv1a2.Kind("Gateway"),
Name: gwapiv1a2.ObjectName("eg"),
},
},
},
ClientIPDetection: &egv1a1.ClientIPDetectionSettings{
XForwardedFor: &egv1a1.XForwardedForSettings{
TrustedCIDRs: []egv1a1.CIDR{
"192.168.1.0/24",
"10.0.0.0/16",
"172.16.0.0/12",
},
},
},
}
},
wantErrors: []string{},
},
{
desc: "http3 enabled and ALPN protocols not set with other TLS parameters set",
mutate: func(ctp *egv1a1.ClientTrafficPolicy) {
Expand Down