diff --git a/internal/mode/static/nginx/config/http/config.go b/internal/mode/static/nginx/config/http/config.go index 854ac109a2..ee45daf98c 100644 --- a/internal/mode/static/nginx/config/http/config.go +++ b/internal/mode/static/nginx/config/http/config.go @@ -110,7 +110,7 @@ type ProxySSLVerify struct { // ServerConfig holds configuration for an HTTP server and IP family to be used by NGINX. type ServerConfig struct { Servers []Server - RewriteClientIP RewriteClientIPSettings + RewriteClientIP shared.RewriteClientIPSettings IPFamily shared.IPFamily Plus bool } @@ -120,11 +120,3 @@ type Include struct { Name string Content []byte } - -// RewriteClientIP holds the configuration for the rewrite client IP settings. -type RewriteClientIPSettings struct { - RealIPHeader string - RealIPFrom []string - Recursive bool - ProxyProtocol bool -} diff --git a/internal/mode/static/nginx/config/servers.go b/internal/mode/static/nginx/config/servers.go index d0171f4d70..1d19ddae97 100644 --- a/internal/mode/static/nginx/config/servers.go +++ b/internal/mode/static/nginx/config/servers.go @@ -909,8 +909,8 @@ func isNonSlashedPrefixPath(pathType dataplane.PathType, path string) bool { } // getRewriteClientIPSettings returns the configuration for the rewriting client IP settings. -func getRewriteClientIPSettings(rewriteIP dataplane.RewriteClientIPSettings) http.RewriteClientIPSettings { - return http.RewriteClientIPSettings{ +func getRewriteClientIPSettings(rewriteIP dataplane.RewriteClientIPSettings) shared.RewriteClientIPSettings { + return shared.RewriteClientIPSettings{ Recursive: rewriteIP.IPRecursive, ProxyProtocol: rewriteIP.Mode == dataplane.RewriteIPModeProxyProtocol, RealIPFrom: rewriteIP.TrustedCIDRs, diff --git a/internal/mode/static/nginx/config/servers_template.go b/internal/mode/static/nginx/config/servers_template.go index bc8df2af3f..cb16dfc62e 100644 --- a/internal/mode/static/nginx/config/servers_template.go +++ b/internal/mode/static/nginx/config/servers_template.go @@ -15,13 +15,17 @@ server { listen [::]:{{ $s.Listen }} ssl default_server{{ $proxyProtocol }}; {{- end }} ssl_reject_handshake on; - {{- range $cidr := $.RewriteClientIP.RealIPFrom }} + {{- if and ($.RewriteClientIP.ProxyProtocol) ($s.IsSocket)}} + set_real_ip_from unix:; + {{- else if (not $s.IsSocket)}} + {{- range $cidr := $.RewriteClientIP.RealIPFrom }} set_real_ip_from {{ $cidr }}; - {{- end}} - {{- if $.RewriteClientIP.RealIPHeader}} + {{- end}} + {{ end }} + {{- if and ($.RewriteClientIP.RealIPHeader) (not $s.IsSocket)}} real_ip_header {{ $.RewriteClientIP.RealIPHeader }}; {{- end}} - {{- if $.RewriteClientIP.Recursive }} + {{- if and ($.RewriteClientIP.Recursive) (not $s.IsSocket)}} real_ip_recursive on; {{ end }} } @@ -33,13 +37,17 @@ server { {{- if $.IPFamily.IPv6 }} listen [::]:{{ $s.Listen }} default_server{{ $proxyProtocol }}; {{- end }} - {{- range $cidr := $.RewriteClientIP.RealIPFrom }} + {{- if and ($.RewriteClientIP.ProxyProtocol) ($s.IsSocket)}} + set_real_ip_from unix:; + {{- else if (not $s.IsSocket)}} + {{- range $cidr := $.RewriteClientIP.RealIPFrom }} set_real_ip_from {{ $cidr }}; - {{- end}} - {{- if $.RewriteClientIP.RealIPHeader}} + {{- end}} + {{ end }} + {{- if and ($.RewriteClientIP.RealIPHeader) (not $s.IsSocket)}} real_ip_header {{ $.RewriteClientIP.RealIPHeader }}; {{- end}} - {{- if $.RewriteClientIP.Recursive }} + {{- if and ($.RewriteClientIP.Recursive) (not $s.IsSocket)}} real_ip_recursive on; {{ end }} default_type text/html; @@ -79,13 +87,17 @@ server { include {{ $i.Name }}; {{- end }} - {{- range $cidr := $.RewriteClientIP.RealIPFrom }} + {{- if and ($.RewriteClientIP.ProxyProtocol) ($s.IsSocket)}} + set_real_ip_from unix:; + {{- else if (not $s.IsSocket)}} + {{- range $cidr := $.RewriteClientIP.RealIPFrom }} set_real_ip_from {{ $cidr }}; {{- end}} - {{- if $.RewriteClientIP.RealIPHeader}} + {{ end }} + {{- if and ($.RewriteClientIP.RealIPHeader) (not $s.IsSocket)}} real_ip_header {{ $.RewriteClientIP.RealIPHeader }}; {{- end}} - {{- if $.RewriteClientIP.Recursive }} + {{- if and ($.RewriteClientIP.Recursive) (not $s.IsSocket)}} real_ip_recursive on; {{ end }} diff --git a/internal/mode/static/nginx/config/servers_test.go b/internal/mode/static/nginx/config/servers_test.go index ece16a8c03..5946106a56 100644 --- a/internal/mode/static/nginx/config/servers_test.go +++ b/internal/mode/static/nginx/config/servers_test.go @@ -284,37 +284,40 @@ func TestExecuteServers_IPFamily(t *testing.T) { } func TestExecuteServers_RewriteClientIP(t *testing.T) { + httpServers := []dataplane.VirtualServer{ + { + IsDefault: true, + Port: 8080, + }, + { + Hostname: "example.com", + Port: 8080, + }, + } + + sslServers := []dataplane.VirtualServer{ + { + IsDefault: true, + Port: 8443, + }, + { + Hostname: "example.com", + SSL: &dataplane.SSL{ + KeyPairID: "test-keypair", + }, + Port: 8443, + }, + } tests := []struct { msg string expectedHTTPConfig map[string]int config dataplane.Configuration }{ { - msg: "http and ssl servers with rewrite client IP settings", + msg: "rewrite client IP settings configured with proxy protocol", config: dataplane.Configuration{ - HTTPServers: []dataplane.VirtualServer{ - { - IsDefault: true, - Port: 8080, - }, - { - Hostname: "example.com", - Port: 8080, - }, - }, - SSLServers: []dataplane.VirtualServer{ - { - IsDefault: true, - Port: 8443, - }, - { - Hostname: "example.com", - SSL: &dataplane.SSL{ - KeyPairID: "test-keypair", - }, - Port: 8443, - }, - }, + HTTPServers: httpServers, + SSLServers: sslServers, BaseHTTPConfig: dataplane.BaseHTTPConfig{ IPFamily: dataplane.Dual, RewriteClientIPSettings: dataplane.RewriteClientIPSettings{ @@ -328,6 +331,7 @@ func TestExecuteServers_RewriteClientIP(t *testing.T) { "set_real_ip_from 0.0.0.0/0;": 4, "real_ip_header proxy_protocol;": 4, "real_ip_recursive on;": 4, + "proxy_protocol on;": 0, "listen 8080 default_server proxy_protocol;": 1, "listen 8080 proxy_protocol;": 1, "listen 8443 ssl default_server proxy_protocol;": 1, @@ -342,6 +346,39 @@ func TestExecuteServers_RewriteClientIP(t *testing.T) { "listen [::]:8443 ssl proxy_protocol;": 1, }, }, + { + msg: "rewrite client IP settings configured with x-forwarded-for", + config: dataplane.Configuration{ + HTTPServers: httpServers, + SSLServers: sslServers, + BaseHTTPConfig: dataplane.BaseHTTPConfig{ + IPFamily: dataplane.Dual, + RewriteClientIPSettings: dataplane.RewriteClientIPSettings{ + Mode: dataplane.RewriteIPModeXForwardedFor, + TrustedCIDRs: []string{"0.0.0.0/0"}, + IPRecursive: true, + }, + }, + }, + expectedHTTPConfig: map[string]int{ + "set_real_ip_from 0.0.0.0/0;": 4, + "real_ip_header X-Forwarded-For;": 4, + "real_ip_recursive on;": 4, + "proxy_protocol on;": 0, + "listen 8080 default_server;": 1, + "listen 8080;": 1, + "listen 8443 ssl default_server;": 1, + "listen 8443 ssl;": 1, + "server_name example.com;": 2, + "ssl_certificate /etc/nginx/secrets/test-keypair.pem;": 1, + "ssl_certificate_key /etc/nginx/secrets/test-keypair.pem;": 1, + "ssl_reject_handshake on;": 1, + "listen [::]:8080 default_server;": 1, + "listen [::]:8080;": 1, + "listen [::]:8443 ssl default_server;": 1, + "listen [::]:8443 ssl;": 1, + }, + }, } for _, test := range tests { diff --git a/internal/mode/static/nginx/config/shared/config.go b/internal/mode/static/nginx/config/shared/config.go index 65c0c873f5..eada321715 100644 --- a/internal/mode/static/nginx/config/shared/config.go +++ b/internal/mode/static/nginx/config/shared/config.go @@ -19,3 +19,11 @@ type IPFamily struct { IPv4 bool IPv6 bool } + +// RewriteClientIP holds the configuration for the rewrite client IP settings. +type RewriteClientIPSettings struct { + RealIPHeader string + RealIPFrom []string + Recursive bool + ProxyProtocol bool +} diff --git a/internal/mode/static/nginx/config/stream/config.go b/internal/mode/static/nginx/config/stream/config.go index 6a3687306c..0bbebadc20 100644 --- a/internal/mode/static/nginx/config/stream/config.go +++ b/internal/mode/static/nginx/config/stream/config.go @@ -26,7 +26,8 @@ type UpstreamServer struct { // ServerConfig holds configuration for a stream server and IP family to be used by NGINX. type ServerConfig struct { - Servers []Server - IPFamily shared.IPFamily - Plus bool + Servers []Server + RewriteClientIP shared.RewriteClientIPSettings + IPFamily shared.IPFamily + Plus bool }