Skip to content

Commit

Permalink
update stream servers config
Browse files Browse the repository at this point in the history
  • Loading branch information
salonichf5 committed Aug 22, 2024
1 parent 72d840b commit 64f1278
Show file tree
Hide file tree
Showing 9 changed files with 222 additions and 43 deletions.
10 changes: 1 addition & 9 deletions internal/mode/static/nginx/config/http/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
4 changes: 2 additions & 2 deletions internal/mode/static/nginx/config/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 9 additions & 0 deletions internal/mode/static/nginx/config/servers_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ server {
{{- if $.RewriteClientIP.Recursive }}
real_ip_recursive on;
{{ end }}
{{ if $.RewriteClientIP.ProxyProtocol }}
proxy_protocol on;
{{ end }}
}
{{- else if $s.IsDefaultHTTP }}
server {
Expand All @@ -42,6 +45,9 @@ server {
{{- if $.RewriteClientIP.Recursive }}
real_ip_recursive on;
{{ end }}
{{ if $.RewriteClientIP.ProxyProtocol }}
proxy_protocol on;
{{ end }}
default_type text/html;
return 404;
}
Expand Down Expand Up @@ -88,6 +94,9 @@ server {
{{- if $.RewriteClientIP.Recursive }}
real_ip_recursive on;
{{ end }}
{{ if $.RewriteClientIP.ProxyProtocol }}
proxy_protocol on;
{{ end }}
{{ range $l := $s.Locations }}
location {{ $l.Path }} {
Expand Down
86 changes: 62 additions & 24 deletions internal/mode/static/nginx/config/servers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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;": 4,
"listen 8080 default_server proxy_protocol;": 1,
"listen 8080 proxy_protocol;": 1,
"listen 8443 ssl default_server proxy_protocol;": 1,
Expand All @@ -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 {
Expand All @@ -355,6 +392,7 @@ func TestExecuteServers_RewriteClientIP(t *testing.T) {
httpMatchConf := string(results[1].data)
g.Expect(httpMatchConf).To(Equal("{}"))

fmt.Println(serverConf)
for expSubStr, expCount := range test.expectedHTTPConfig {
g.Expect(strings.Count(serverConf, expSubStr)).To(Equal(expCount))
}
Expand Down
8 changes: 8 additions & 0 deletions internal/mode/static/nginx/config/shared/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
7 changes: 4 additions & 3 deletions internal/mode/static/nginx/config/stream/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
7 changes: 4 additions & 3 deletions internal/mode/static/nginx/config/stream_servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ func (g GeneratorImpl) executeStreamServers(conf dataplane.Configuration) []exec
streamServers := createStreamServers(conf)

streamServerConfig := stream.ServerConfig{
Servers: streamServers,
IPFamily: getIPFamily(conf.BaseHTTPConfig),
Plus: g.plus,
Servers: streamServers,
IPFamily: getIPFamily(conf.BaseHTTPConfig),
Plus: g.plus,
RewriteClientIP: getRewriteClientIPSettings(conf.BaseHTTPConfig.RewriteClientIPSettings),
}

streamServerResult := executeResult{
Expand Down
19 changes: 17 additions & 2 deletions internal/mode/static/nginx/config/stream_servers_template.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
package config

const streamServersTemplateText = `
{{ $proxyProtocol := "" }}
{{ if $.RewriteClientIP.ProxyProtocol }}{{ $proxyProtocol = " proxy_protocol" }}{{ end }}
{{- range $s := .Servers }}
server {
{{- if or ($.IPFamily.IPv4) ($s.IsSocket) }}
listen {{ $s.Listen }};
listen {{ $s.Listen }}{{ $proxyProtocol }};
{{- end }}
{{- if and ($.IPFamily.IPv6) (not $s.IsSocket) }}
listen [::]:{{ $s.Listen }};
listen [::]:{{ $s.Listen }}{{ $proxyProtocol }};
{{- end }}
{{- 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}}
{{ end }}
{{- if and ($.RewriteClientIP.ProxyProtocol) (not $s.IsSocket)}}
proxy_protocol on;
{{- end }}
{{- if $.Plus }}
Expand Down
115 changes: 115 additions & 0 deletions internal/mode/static/nginx/config/stream_servers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,118 @@ func TestCreateStreamServersWithNone(t *testing.T) {

g.Expect(streamServers).To(BeNil())
}

func TestExecuteStreamServers_RewriteClientIP(t *testing.T) {
passThroughServers := []dataplane.Layer4VirtualServer{
{
UpstreamName: "backend1",
Hostname: "cafe.example.com",
Port: 8443,
},
{
UpstreamName: "backend2",
Hostname: "tea.example.com",
Port: 8443,
},
}
streamUpstreams := []dataplane.Upstream{
{
Name: "backend1",
Endpoints: []resolver.Endpoint{
{
Address: "1.1.1.1",
},
},
},
{
Name: "backend2",
Endpoints: []resolver.Endpoint{
{
Address: "1.1.1.1",
},
},
},
}

tests := []struct {
msg string
expectedServerConfig map[string]int
config dataplane.Configuration
}{
{
msg: "tls servers with no rewrite client IP settings",
config: dataplane.Configuration{
BaseHTTPConfig: dataplane.BaseHTTPConfig{},
TLSPassthroughServers: passThroughServers,
StreamUpstreams: streamUpstreams,
},
expectedServerConfig: map[string]int{
"listen 8443;": 1,
"listen unix:/var/run/nginx/cafe.example.com-8443.sock;": 1,
},
},
{
msg: "tls servers with rewrite client IP settings configured with proxy protocol",
config: dataplane.Configuration{
BaseHTTPConfig: dataplane.BaseHTTPConfig{
RewriteClientIPSettings: dataplane.RewriteClientIPSettings{
Mode: dataplane.RewriteIPModeProxyProtocol,
TrustedCIDRs: []string{"1.1.1.1/32"},
IPRecursive: true,
},
},
TLSPassthroughServers: passThroughServers,
StreamUpstreams: streamUpstreams,
},
expectedServerConfig: map[string]int{
"listen 8443 proxy_protocol;": 1,
" listen [::]:8443 proxy_protocol;": 1,
"listen unix:/var/run/nginx/cafe.example.com-8443.sock proxy_protocol;": 1,
"set_real_ip_from unix:;": 2,
"real_ip_header proxy_protocol;": 0,
"real_ip_recursive on;": 0,
"set_real_ip_from 1.1.1.1/32;": 1,
"proxy_protocol on;": 1,
},
},
{
msg: "tls servers with rewrite client IP settings configured with xforwardedfor",
config: dataplane.Configuration{
BaseHTTPConfig: dataplane.BaseHTTPConfig{
RewriteClientIPSettings: dataplane.RewriteClientIPSettings{
Mode: dataplane.RewriteIPModeXForwardedFor,
TrustedCIDRs: []string{"1.1.1.1/32"},
IPRecursive: true,
},
},
TLSPassthroughServers: passThroughServers,
StreamUpstreams: streamUpstreams,
},
expectedServerConfig: map[string]int{
"listen 8443;": 1,
" listen [::]:8443;": 1,
"listen unix:/var/run/nginx/cafe.example.com-8443.sock;": 1,
"set_real_ip_from unix:;": 0,
"real_ip_header X-Forwarded-For;": 0,
"real_ip_recursive on;": 0,
"set_real_ip_from 1.1.1.1/32;": 1,
"proxy_protocol on;": 0,
},
},
}

for _, test := range tests {
t.Run(test.msg, func(t *testing.T) {
g := NewWithT(t)

gen := GeneratorImpl{}
results := gen.executeStreamServers(test.config)
g.Expect(results).To(HaveLen(1))
serverConf := string(results[0].data)

for expSubStr, expCount := range test.expectedServerConfig {
g.Expect(strings.Count(serverConf, expSubStr)).To(Equal(expCount))
}
})
}
}

0 comments on commit 64f1278

Please sign in to comment.