Skip to content
Draft
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
2 changes: 2 additions & 0 deletions internal/configs/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,7 @@ func generateNginxCfg(ncp NginxCfgParams) (version1.IngressNginxConfig, Warnings
StaticSSLPath: ncp.staticParams.StaticSSLPath,
LimitReqZones: limitReqZones,
Maps: removeDuplicateMaps(maps),
AppProtectLoadModule: ncp.staticParams.MainAppProtectLoadModule,
}, allWarnings
}

Expand Down Expand Up @@ -1415,6 +1416,7 @@ func generateNginxCfgForMergeableIngresses(ncp NginxCfgParams) (version1.Ingress
StaticSSLPath: ncp.staticParams.StaticSSLPath,
LimitReqZones: limitReqZones,
Maps: removeDuplicateMaps(maps),
AppProtectLoadModule: ncp.staticParams.MainAppProtectLoadModule,
}, warnings
}

Expand Down
2 changes: 2 additions & 0 deletions internal/configs/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4524,6 +4524,7 @@ func TestGenerateNginxCfgForAppProtect(t *testing.T) {
expected.Servers[0].AppProtectLogConfs = []string{"/etc/nginx/waf/nac-logconfs/default_logconf syslog:server=127.0.0.1:514"}
expected.Servers[0].AppProtectLogEnable = "on"
expected.Ingress.Annotations = cafeIngressEx.Ingress.Annotations
expected.AppProtectLoadModule = true

result, warnings := generateNginxCfg(NginxCfgParams{
staticParams: staticCfgParams,
Expand Down Expand Up @@ -4587,6 +4588,7 @@ func TestGenerateNginxCfgForMergeableIngressesForAppProtect(t *testing.T) {
expected.Servers[0].AppProtectLogConfs = []string{"/etc/nginx/waf/nac-logconfs/default_logconf syslog:server=127.0.0.1:514"}
expected.Servers[0].AppProtectLogEnable = "on"
expected.Ingress.Annotations = mergeableIngresses.Master.Ingress.Annotations
expected.AppProtectLoadModule = true

result, warnings := generateNginxCfgForMergeableIngresses(NginxCfgParams{
mergeableIngs: mergeableIngresses,
Expand Down
68 changes: 68 additions & 0 deletions internal/configs/version1/__snapshots__/template_test.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3409,6 +3409,74 @@ server {

---

[TestExecuteTemplate_ForIngressForNGINXPlus_DisablesWAFOnInternalLocations/module_loaded_disables_WAF_on_internal_locations - 1]
# configuration for default/ing
upstream test-upstream {
zone test-upstream 256k;
server 10.0.0.20:8001 max_fails=0 fail_timeout= max_conns=0;
}


server {

server_tokens "off";

server_name example.com;

status_zone example.com;
set $resource_type "ingress";
set $resource_name "ing";
set $resource_namespace "default";
set $service "-";




location / {
set $service "svc";
status_zone "svc";
proxy_http_version 1.1;

proxy_connect_timeout ;
proxy_read_timeout ;
proxy_send_timeout ;
client_max_body_size ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_pass ;

}

location /_external_auth/authsvc {
set $service "authsvc";
internal;
app_protect_enable off;
proxy_http_version 1.1;

proxy_connect_timeout ;
proxy_read_timeout ;
proxy_send_timeout ;
client_max_body_size ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_pass http://ext-auth-authsvc/verify;

}

}

---

[TestExecuteTemplate_ForIngressForNGINXRewriteTarget/case_insensitive_regex_rewrite - 1]
# configuration for default/cafe-ingress

Expand Down
4 changes: 4 additions & 0 deletions internal/configs/version1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ type IngressNginxConfig struct {
DynamicSSLReloadEnabled bool
StaticSSLPath string
LimitReqZones []LimitReqZone
// AppProtectLoadModule mirrors the controller's -enable-app-protect flag so
// templates can safely emit app_protect_enable off; in internal sub-request
// locations only when the WAF module is actually loaded.
AppProtectLoadModule bool
}

// Ingress holds information about an Ingress resource.
Expand Down
3 changes: 3 additions & 0 deletions internal/configs/version1/nginx-plus.ingress.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ server {
{{- end}}
{{- if $location.Internal}}
internal;
{{- if $.AppProtectLoadModule}}
app_protect_enable off;
{{- end}}
{{- end}}
{{- with $location.MinionIngress}}
# location for minion {{$location.MinionIngress.Namespace}}/{{$location.MinionIngress.Name}}
Expand Down
65 changes: 65 additions & 0 deletions internal/configs/version1/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,71 @@ func TestExecuteTemplate_ForIngressForNGINXPlus(t *testing.T) {
snaps.MatchSnapshot(t, buf.String())
}

func TestExecuteTemplate_ForIngressForNGINXPlus_DisablesWAFOnInternalLocations(t *testing.T) {
t.Parallel()

baseCfg := IngressNginxConfig{
Upstreams: []Upstream{
{Name: "test-upstream", UpstreamServers: []UpstreamServer{{Address: "10.0.0.20:8001"}}, UpstreamZoneSize: "256k"},
},
Servers: []Server{
{
Name: "example.com",
StatusZone: "example.com",
ServerTokens: "off",
Locations: []Location{
{Path: "/", Upstream: Upstream{Name: "test-upstream"}, ServiceName: "svc"},
{
Path: "/_external_auth/authsvc",
Internal: true,
ProxyPass: "http://ext-auth-authsvc/verify",
ServiceName: "authsvc",
},
},
},
},
Ingress: Ingress{Name: "ing", Namespace: "default"},
}

t.Run("module not loaded emits no override", func(t *testing.T) {
t.Parallel()
tmpl := newNGINXPlusIngressTmpl(t)
buf := &bytes.Buffer{}
cfg := baseCfg
if err := tmpl.Execute(buf, cfg); err != nil {
t.Fatal(err)
}
if bytes.Contains(buf.Bytes(), []byte("app_protect_enable off;")) {
t.Errorf("expected no app_protect_enable off; when AppProtectLoadModule is false, got:\n%s", buf.String())
}
})

t.Run("module loaded disables WAF on internal locations", func(t *testing.T) {
t.Parallel()
tmpl := newNGINXPlusIngressTmpl(t)
buf := &bytes.Buffer{}
cfg := baseCfg
cfg.AppProtectLoadModule = true
if err := tmpl.Execute(buf, cfg); err != nil {
t.Fatal(err)
}
out := buf.Bytes()
marker := []byte("location /_external_auth/authsvc")
idx := bytes.Index(out, marker)
if idx < 0 {
t.Fatalf("marker %q missing from rendered template", marker)
}
end := idx + 400
if end > len(out) {
end = len(out)
}
if !bytes.Contains(out[idx:end], []byte("app_protect_enable off;")) {
t.Errorf("missing app_protect_enable off; inside external auth location\nrendered slice:\n%s", out[idx:end])
}
snaps.MatchSnapshot(t, buf.String())
})
}

func TestExecuteTemplate_ForIngressForNGINX(t *testing.T) {
t.Parallel()

Expand Down
Loading
Loading