Skip to content

Commit

Permalink
change trustedAddress type to struct
Browse files Browse the repository at this point in the history
  • Loading branch information
salonichf5 committed Sep 5, 2024
1 parent 38d115a commit 7ee4806
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 105 deletions.
39 changes: 28 additions & 11 deletions apis/v1alpha1/nginxproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ type RewriteClientIP struct {
// If enabled, NGINX will recurse on the values in X-Forwarded-Header from the end of array
// to start of array and select the first untrusted IP.
// For example, if X-Forwarded-For is [11.11.11.11, 22.22.22.22, 55.55.55.1],
// and TrustedAddresses is set to 55.55.55.1, NGINX will rewrite the client IP to 22.22.22.22.
// and TrustedAddresses is set to 55.55.55.1/32, NGINX will rewrite the client IP to 22.22.22.22.
// If disabled, NGINX will select the IP at the end of the array.
// In the previous example, 55.55.55.1 would be selected.
// Sets NGINX directive real_ip_recursive: https://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive
Expand All @@ -149,17 +149,17 @@ type RewriteClientIP struct {
// If a request comes from a trusted address, NGINX will rewrite the client IP information,
// and forward it to the backend in the X-Forwarded-For* and X-Real-IP headers.
// If the request does not come from a trusted address, NGINX will not rewrite the client IP information.
// Addresses must be provided as CIDR blocks or IP addresses: 10.0.0.0, 192.33.21/24, fe80::1/128.
// TrustedAddresses only supports CIDR blocks: 192.33.21.1/24, fe80::1/64.
// To trust all addresses (not recommended for production), set to 0.0.0.0/0.
// If no addresses are provided, NGINX will not rewrite the client IP information.
// Sets NGINX directive set_real_ip_from: https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from
// This field is required if mode is set.
// +kubebuilder:validation:MaxItems=16
// +listType=set
// +listType=atomic
//
//
// +optional
TrustedAddresses []TrustedAddress `json:"trustedAddresses,omitempty"`
TrustedAddresses []Address `json:"trustedAddresses,omitempty"`
}

// RewriteClientIPModeType defines how NGINX Gateway Fabric will determine the client's original IP address.
Expand All @@ -179,10 +179,27 @@ const (
RewriteClientIPModeXForwardedFor RewriteClientIPModeType = "XForwardedFor"
)

// TrustedAddress is a string value representing a CIDR block or an IP address.
// Examples: 10.0.0.2/32, 10.0.0.1, fe80::1/128, ::1/24.
//
// +kubebuilder:validation:Pattern=`^(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}(?:\/(?:[0-9]|[12][0-9]|3[0-2]))?|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}(?:\/(?:[0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?)$`
//
//nolint:lll
type TrustedAddress string
// Address is a struct that specifies address type and value.
type Address struct {
// Type specifies the type of address.
// Default is "cidr" which specifies that the address is a CIDR block.
//
// +optional
// +kubebuilder:default:=cidr
Type AddressType `json:"type,omitempty"`

// Value specifies the address value.
//
// +optional
Value string `json:"value,omitempty"`
}

// AddressType specifies the type of address.
// +kubebuilder:validation:Enum=cidr
type AddressType string

const (
// AddressTypeCIDR specifies that the address is a CIDR block.
// kubebuilder:validation:Pattern=`(\/([0-9]?[0-9]?[0-8]))$`
AddressTypeCIDR AddressType = "cidr"
)
17 changes: 16 additions & 1 deletion apis/v1alpha1/zz_generated.deepcopy.go

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

26 changes: 18 additions & 8 deletions config/crd/bases/gateway.nginx.org_nginxproxies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ spec:
If enabled, NGINX will recurse on the values in X-Forwarded-Header from the end of array
to start of array and select the first untrusted IP.
For example, if X-Forwarded-For is [11.11.11.11, 22.22.22.22, 55.55.55.1],
and TrustedAddresses is set to 55.55.55.1, NGINX will rewrite the client IP to 22.22.22.22.
and TrustedAddresses is set to 55.55.55.1/32, NGINX will rewrite the client IP to 22.22.22.22.
If disabled, NGINX will select the IP at the end of the array.
In the previous example, 55.55.55.1 would be selected.
Sets NGINX directive real_ip_recursive: https://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive
Expand All @@ -95,20 +95,30 @@ spec:
If a request comes from a trusted address, NGINX will rewrite the client IP information,
and forward it to the backend in the X-Forwarded-For* and X-Real-IP headers.
If the request does not come from a trusted address, NGINX will not rewrite the client IP information.
Addresses must be provided as CIDR blocks or IP addresses: 10.0.0.0, 192.33.21/24, fe80::1/128.
TrustedAddresses only supports CIDR blocks: 192.33.21.1/24, fe80::1/64.
To trust all addresses (not recommended for production), set to 0.0.0.0/0.
If no addresses are provided, NGINX will not rewrite the client IP information.
Sets NGINX directive set_real_ip_from: https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from
This field is required if mode is set.
items:
description: |-
TrustedAddress is a string value representing a CIDR block or an IP address.
Examples: 10.0.0.2/32, 10.0.0.1, fe80::1/128, ::1/24.
pattern: ^(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}(?:\/(?:[0-9]|[12][0-9]|3[0-2]))?|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}(?:\/(?:[0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?)$
type: string
description: Address is a struct that specifies address type
and value.
properties:
type:
default: cidr
description: |-
Type specifies the type of address.
Default is "cidr" which specifies that the address is a CIDR block.
enum:
- cidr
type: string
value:
description: Value specifies the address value.
type: string
type: object
maxItems: 16
type: array
x-kubernetes-list-type: set
x-kubernetes-list-type: atomic
type: object
x-kubernetes-validations:
- message: if mode is set, trustedAddresses is a required field
Expand Down
26 changes: 18 additions & 8 deletions deploy/crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ spec:
If enabled, NGINX will recurse on the values in X-Forwarded-Header from the end of array
to start of array and select the first untrusted IP.
For example, if X-Forwarded-For is [11.11.11.11, 22.22.22.22, 55.55.55.1],
and TrustedAddresses is set to 55.55.55.1, NGINX will rewrite the client IP to 22.22.22.22.
and TrustedAddresses is set to 55.55.55.1/32, NGINX will rewrite the client IP to 22.22.22.22.
If disabled, NGINX will select the IP at the end of the array.
In the previous example, 55.55.55.1 would be selected.
Sets NGINX directive real_ip_recursive: https://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive
Expand All @@ -680,20 +680,30 @@ spec:
If a request comes from a trusted address, NGINX will rewrite the client IP information,
and forward it to the backend in the X-Forwarded-For* and X-Real-IP headers.
If the request does not come from a trusted address, NGINX will not rewrite the client IP information.
Addresses must be provided as CIDR blocks or IP addresses: 10.0.0.0, 192.33.21/24, fe80::1/128.
TrustedAddresses only supports CIDR blocks: 192.33.21.1/24, fe80::1/64.
To trust all addresses (not recommended for production), set to 0.0.0.0/0.
If no addresses are provided, NGINX will not rewrite the client IP information.
Sets NGINX directive set_real_ip_from: https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from
This field is required if mode is set.
items:
description: |-
TrustedAddress is a string value representing a CIDR block or an IP address.
Examples: 10.0.0.2/32, 10.0.0.1, fe80::1/128, ::1/24.
pattern: ^(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}(?:\/(?:[0-9]|[12][0-9]|3[0-2]))?|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}(?:\/(?:[0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?)$
type: string
description: Address is a struct that specifies address type
and value.
properties:
type:
default: cidr
description: |-
Type specifies the type of address.
Default is "cidr" which specifies that the address is a CIDR block.
enum:
- cidr
type: string
value:
description: Value specifies the address value.
type: string
type: object
maxItems: 16
type: array
x-kubernetes-list-type: set
x-kubernetes-list-type: atomic
type: object
x-kubernetes-validations:
- message: if mode is set, trustedAddresses is a required field
Expand Down
12 changes: 6 additions & 6 deletions internal/mode/static/nginx/config/servers_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ server {
listen [::]:{{ $s.Listen }} ssl default_server{{ $.RewriteClientIP.ProxyProtocol }};
{{- end }}
ssl_reject_handshake on;
{{- range $cidr := $.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $cidr }};
{{- range $address := $.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $address }};
{{- end}}
{{- if $.RewriteClientIP.RealIPHeader}}
real_ip_header {{ $.RewriteClientIP.RealIPHeader }};
Expand All @@ -31,8 +31,8 @@ server {
{{- if $.IPFamily.IPv6 }}
listen [::]:{{ $s.Listen }} default_server{{ $.RewriteClientIP.ProxyProtocol }};
{{- end }}
{{- range $cidr := $.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $cidr }};
{{- range $address := $.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $address }};
{{- end}}
{{- if $.RewriteClientIP.RealIPHeader}}
real_ip_header {{ $.RewriteClientIP.RealIPHeader }};
Expand Down Expand Up @@ -77,8 +77,8 @@ server {
include {{ $i.Name }};
{{- end }}
{{- range $cidr := $.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $cidr }};
{{- range $address := $.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $address }};
{{- end}}
{{- if $.RewriteClientIP.RealIPHeader}}
real_ip_header {{ $.RewriteClientIP.RealIPHeader }};
Expand Down
4 changes: 2 additions & 2 deletions internal/mode/static/nginx/config/stream_servers_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ server {
listen [::]:{{ $s.Listen }};
{{- end }}
{{- range $cidr := $s.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $cidr }};
{{- range $address := $s.RewriteClientIP.RealIPFrom }}
set_real_ip_from {{ $address }};
{{- end}}
{{- if $.Plus }}
status_zone {{ $s.StatusZone }};
Expand Down
6 changes: 3 additions & 3 deletions internal/mode/static/state/dataplane/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ func buildBaseHTTPConfig(g *graph.Graph) BaseHTTPConfig {
}

if len(g.NginxProxy.Source.Spec.RewriteClientIP.TrustedAddresses) > 0 {
baseConfig.RewriteClientIPSettings.TrustedAddresses = convertTrustedAddresses(
baseConfig.RewriteClientIPSettings.TrustedAddresses = convertAddresses(
g.NginxProxy.Source.Spec.RewriteClientIP.TrustedAddresses,
)
}
Expand Down Expand Up @@ -894,10 +894,10 @@ func buildPolicies(graphPolicies []*graph.Policy) []policies.Policy {
return finalPolicies
}

func convertTrustedAddresses(addresses []ngfAPI.TrustedAddress) []string {
func convertAddresses(addresses []ngfAPI.Address) []string {
trustedAddresses := make([]string, len(addresses))
for i, addr := range addresses {
trustedAddresses[i] = string(addr)
trustedAddresses[i] = addr.Value
}
return trustedAddresses
}
54 changes: 43 additions & 11 deletions internal/mode/static/state/dataplane/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2198,8 +2198,13 @@ func TestBuildConfiguration(t *testing.T) {
Spec: ngfAPI.NginxProxySpec{
RewriteClientIP: &ngfAPI.RewriteClientIP{
SetIPRecursively: helpers.GetPointer(true),
TrustedAddresses: []ngfAPI.TrustedAddress{"1.1.1.1/32"},
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeProxyProtocol),
TrustedAddresses: []ngfAPI.Address{
{
Type: ngfAPI.AddressTypeCIDR,
Value: "1.1.1.1/32",
},
},
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeProxyProtocol),
},
},
},
Expand Down Expand Up @@ -3619,8 +3624,13 @@ func TestBuildRewriteIPSettings(t *testing.T) {
Source: &ngfAPI.NginxProxy{
Spec: ngfAPI.NginxProxySpec{
RewriteClientIP: &ngfAPI.RewriteClientIP{
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeProxyProtocol),
TrustedAddresses: []ngfAPI.TrustedAddress{"10.9.9.4"},
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeProxyProtocol),
TrustedAddresses: []ngfAPI.Address{
{
Type: ngfAPI.AddressTypeCIDR,
Value: "10.9.9.4/32",
},
},
SetIPRecursively: helpers.GetPointer(true),
},
},
Expand All @@ -3629,7 +3639,7 @@ func TestBuildRewriteIPSettings(t *testing.T) {
},
expRewriteIPSettings: RewriteClientIPSettings{
Mode: RewriteIPModeProxyProtocol,
TrustedAddresses: []string{"10.9.9.4"},
TrustedAddresses: []string{"10.9.9.4/32"},
IPRecursive: true,
},
},
Expand All @@ -3641,8 +3651,13 @@ func TestBuildRewriteIPSettings(t *testing.T) {
Source: &ngfAPI.NginxProxy{
Spec: ngfAPI.NginxProxySpec{
RewriteClientIP: &ngfAPI.RewriteClientIP{
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeXForwardedFor),
TrustedAddresses: []ngfAPI.TrustedAddress{"76.89.90.11"},
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeXForwardedFor),
TrustedAddresses: []ngfAPI.Address{
{
Type: ngfAPI.AddressTypeCIDR,
Value: "76.89.90.11/24",
},
},
SetIPRecursively: helpers.GetPointer(true),
},
},
Expand All @@ -3651,7 +3666,7 @@ func TestBuildRewriteIPSettings(t *testing.T) {
},
expRewriteIPSettings: RewriteClientIPSettings{
Mode: RewriteIPModeXForwardedFor,
TrustedAddresses: []string{"76.89.90.11"},
TrustedAddresses: []string{"76.89.90.11/24"},
IPRecursive: true,
},
},
Expand All @@ -3663,8 +3678,25 @@ func TestBuildRewriteIPSettings(t *testing.T) {
Source: &ngfAPI.NginxProxy{
Spec: ngfAPI.NginxProxySpec{
RewriteClientIP: &ngfAPI.RewriteClientIP{
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeXForwardedFor),
TrustedAddresses: []ngfAPI.TrustedAddress{"5.5.5.5", "1.1.1.1/32", "2.2.2.2/32", "3.3.3.3/24"},
Mode: helpers.GetPointer(ngfAPI.RewriteClientIPModeXForwardedFor),
TrustedAddresses: []ngfAPI.Address{
{
Type: ngfAPI.AddressTypeCIDR,
Value: "5.5.5.5/12",
},
{
Type: ngfAPI.AddressTypeCIDR,
Value: "1.1.1.1/26",
},
{
Type: ngfAPI.AddressTypeCIDR,
Value: "2.2.2.2/32",
},
{
Type: ngfAPI.AddressTypeCIDR,
Value: "3.3.3.3/24",
},
},
SetIPRecursively: helpers.GetPointer(false),
},
},
Expand All @@ -3673,7 +3705,7 @@ func TestBuildRewriteIPSettings(t *testing.T) {
},
expRewriteIPSettings: RewriteClientIPSettings{
Mode: RewriteIPModeXForwardedFor,
TrustedAddresses: []string{"5.5.5.5", "1.1.1.1/32", "2.2.2.2/32", "3.3.3.3/24"},
TrustedAddresses: []string{"5.5.5.5/12", "1.1.1.1/26", "2.2.2.2/32", "3.3.3.3/24"},
IPRecursive: false,
},
},
Expand Down
9 changes: 3 additions & 6 deletions internal/mode/static/state/graph/nginxproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,12 @@ func validateRewriteClientIP(npCfg *ngfAPI.NginxProxy) field.ErrorList {
}

for _, addr := range rewriteClientIP.TrustedAddresses {
cidrError := k8svalidation.IsValidCIDR(trustedAddressesPath, string(addr))
ipError := k8svalidation.IsValidIP(trustedAddressesPath, string(addr))

if cidrError != nil && ipError != nil {
if err := k8svalidation.IsValidCIDR(trustedAddressesPath, addr.Value); err != nil {
allErrs = append(
allErrs,
field.Invalid(trustedAddressesPath.Child(string(addr)),
field.Invalid(trustedAddressesPath.Child(addr.Value),
addr,
"must be a valid IP address or CIDR range",
err.ToAggregate().Error(),
),
)
}
Expand Down
Loading

0 comments on commit 7ee4806

Please sign in to comment.