8000 Add handling of mutiple log destinations · nginx/kubernetes-ingress@f2ad94b · GitHub
[go: up one dir, main page]

Skip to content

Commit f2ad94b

Browse files
author
Rafal Wegrzycki
committed
Add handling of mutiple log destinations
1 parent 6c014f6 commit f2ad94b

File tree

15 files changed

+426
-31
lines changed

15 files changed

+426
-31
lines changed

deployments/common/crds/k8s.nginx.org_policies.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,18 @@ spec:
156156
type: boolean
157157
logDest:
158158
type: string
159+
securityLogs:
160+
type: array
161+
items:
162+
description: SecurityLog defines the security log of a WAF policy.
163+
type: object
164+
properties:
165+
apLogConf:
166+
type: string
167+
enable:
168+
type: boolean
169+
logDest:
170+
type: string
159171
status:
160172
description: PolicyStatus is the status of the policy resource
161173
type: object

deployments/helm-chart/crds/k8s.nginx.org_policies.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,18 @@ spec:
156156
type: boolean
157157
logDest:
158158
type: string
159+
securityLogs:
160+
type: array
161+
items:
162+
description: SecurityLog defines the security log of a WAF policy.
163+
type: object
164+
properties:
165+
apLogConf:
166+
type: string
167+
enable:
168+
type: boolean
169+
logDest:
170+
type: string
159171
status:
160172
description: PolicyStatus is the status of the policy resource
161173
type: object

docs/content/configuration/policy-resource.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,17 +362,20 @@ For `kubectl get` and similar commands, you can also use the short name `pol` in
362362

363363
The WAF policy configures NGINX Plus to secure client requests using App Protect policies.
364364

365-
For example, the following policy will enable the referenced APPolicy and APLogConf with the configured log destination:
365+
For example, the following policy will enable the referenced APPolicy. You can configure multiple APLogConfs with log destinations:
366366
```yaml
367367
waf:
368368
enable: true
369369
apPolicy: "default/dataguard-alarm"
370-
securityLog:
371-
enable: true
370+
securityLogs:
371+
- enable: true
372372
apLogConf: "default/logconf"
373373
logDest: "syslog:server=syslog-svc.default:514"
374+
- enable: true
375+
apLogConf: "default/logconf"
376+
logDest: "syslog:server=syslog-svc-secondary.default:514"
374377
```
375-
378+
> Note: The field `waf.securityLog` is supported but will be ignored if `waf.securityLogs` is populated.
376379
> Note: The feature is implemented using the NGINX Plus [NGINX App Protect Module](https://docs.nginx.com/nginx-app-protect/configuration/).
377380

378381
{{% table %}}

examples/custom-resources/waf/waf.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ spec:
66
waf:
77
enable: true
88
apPolicy: "default/dataguard-alarm"
9-
securityLog:
10-
enable: true
9+
securityLogs:
10+
- enable: true
1111
apLogConf: "default/logconf"
1212
logDest: "syslog:server=syslog-svc.default:514"

internal/configs/version2/http.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ type WAF struct {
123123
Enable string
124124
ApPolicy string
125125
ApSecurityLogEnable bool
126-
ApLogConf string
126+
ApLogConf []string
127127
}
128128

129129
// Dos defines Dos configuration.

internal/configs/version2/nginx-plus.virtualserver.tmpl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ server {
189189

190190
{{ if .ApSecurityLogEnable }}
191191
app_protect_security_log_enable on;
192-
app_protect_security_log {{ .ApLogConf }};
192+
{{ range $logconf := .ApLogConf }}
193+
app_protect_security_log {{ $logconf }};
194+
{{ end }}
193195
{{ end }}
194196
{{ end }}
195197

internal/configs/version2/templates_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ var virtualServerCfg = VirtualServerConfig{
150150
WAF: &WAF{
151151
ApPolicy: "/etc/nginx/waf/nac-policies/default-dataguard-alarm",
152152
ApSecurityLogEnable: true,
153-
ApLogConf: "/etc/nginx/waf/nac-logconfs/default-logconf",
153+
ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf"},
154154
},
155155
Snippets: []string{"# server snippet"},
156156
InternalRedirectLocations: []InternalRedirectLocation{

internal/configs/virtualserver.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ func (p *policiesCfg) addWAFConfig(
10421042
}
10431043
}
10441044

1045-
if waf.SecurityLog != nil {
1045+
if waf.SecurityLog != nil && waf.SecurityLogs == nil {
10461046
p.WAF.ApSecurityLogEnable = true
10471047

10481048
logConfKey := waf.SecurityLog.ApLogConf
@@ -1053,13 +1053,31 @@ func (p *policiesCfg) addWAFConfig(
10531053

10541054
if logConfPath, ok := apResources.LogConfs[logConfKey]; ok {
10551055
logDest := generateString(waf.SecurityLog.LogDest, "syslog:server=localhost:514")
1056-
p.WAF.ApLogConf = fmt.Sprintf("%s %s", logConfPath, logDest)
1056+
p.WAF.ApLogConf = []string{fmt.Sprintf("%s %s", logConfPath, logDest)}
10571057
} else {
10581058
res.addWarningf("WAF policy %s references an invalid or non-existing log config %s", polKey, logConfKey)
10591059
res.isError = true
10601060
}
10611061
}
10621062

1063+
if waf.SecurityLogs != nil {
1064+
p.WAF.ApSecurityLogEnable = true
1065+
p.WAF.ApLogConf = []string{}
1066+
for _, loco := range waf.SecurityLogs {
1067+
logConfKey := loco.ApLogConf
1068+
hasNamepace := strings.Contains(logConfKey, "/")
1069+
if !hasNamepace {
1070+
logConfKey = fmt.Sprintf("%v/%v", polNamespace, logConfKey)
1071+
}
1072+
if logConfPath, ok := apResources.LogConfs[logConfKey]; ok {
1073+
logDest := generateString(loco.LogDest, "syslog:server=localhost:514")
1074+
p.WAF.ApLogConf = append(p.WAF.ApLogConf, fmt.Sprintf("%s %s", logConfPath, logDest))
1075+
} else {
1076+
res.addWarningf("WAF policy %s references an invalid or non-existing log config %s", polKey, logConfKey)
1077+
res.isError = true
1078+
}
1079+
}
1080+
}
10631081
return res
10641082
}
10651083

internal/configs/virtualserver_test.go

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,7 +2924,7 @@ func TestGeneratePolicies(t *testing.T) {
29242924
Enable: "on",
29252925
ApPolicy: "/etc/nginx/waf/nac-policies/default-dataguard-alarm",
29262926
ApSecurityLogEnable: true,
2927-
ApLogConf: "/etc/nginx/waf/nac-logconfs/default-logconf syslog:server=127.0.0.1:514",
2927+
ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf syslog:server=127.0.0.1:514"},
29282928
},
29292929
},
29302930
msg: "WAF reference",
@@ -8214,7 +8214,38 @@ func TestAddWafConfig(t *testing.T) {
82148214
wafConfig: &version2.WAF{
82158215
ApPolicy: "/etc/nginx/waf/nac-policies/default-dataguard-alarm",
82168216
ApSecurityLogEnable: true,
8217-
ApLogConf: "/etc/nginx/waf/nac-logconfs/default-logconf",
8217+
ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf"},
8218+
},
8219+
expected: &validationResults{isError: false},
8220+
msg: "valid waf config",
8221+
},
8222+
{
8223+
8224+
wafInput: &conf_v1.WAF{
8225+
Enable: true,
8226+
ApPolicy: "dataguard-alarm",
8227+
SecurityLogs: []*conf_v1.SecurityLog{
8228+
{
8229+
Enable: true,
8230+
ApLogConf: "logconf",
8231+
LogDest: "syslog:server=127.0.0.1:514",
8232+
},
8233+
},
8234+
},
8235+
polKey: "default/waf-policy",
8236+
polNamespace: "default",
8237+
apResources: &appProtectResourcesForVS{
8238+
Policies: map[string]string{
8239+
"default/dataguard-alarm": "/etc/nginx/waf/nac-policies/default-dataguard-alarm",
8240+
},
8241+
LogConfs: map[string]string{
8242+
"default/logconf": "/etc/nginx/waf/nac-logconfs/default-logconf",
8243+
},
8244+
},
8245+
wafConfig: &version2.WAF{
8246+
ApPolicy: "/etc/nginx/waf/nac-policies/default-dataguard-alarm",
8247+
ApSecurityLogEnable: true,
8248+
ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf"},
82188249
},
82198250
expected: &validationResults{isError: false},
82208251
msg: "valid waf config",
@@ -8241,7 +8272,7 @@ func TestAddWafConfig(t *testing.T) {
82418272
wafConfig: &version2.WAF{
82428273
ApPolicy: "/etc/nginx/waf/nac-policies/default-dataguard-alarm",
82438274
ApSecurityLogEnable: true,
8244-
ApLogConf: "/etc/nginx/waf/nac-logconfs/default-logconf",
8275+
ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf"},
82458276
},
82468277
expected: &validationResults{
82478278
isError: true,
@@ -8272,7 +8303,7 @@ func TestAddWafConfig(t *testing.T) {
82728303
wafConfig: &version2.WAF{
82738304
ApPolicy: "/etc/nginx/waf/nac-policies/default-dataguard-alarm",
82748305
ApSecurityLogEnable: true,
8275-
ApLogConf: "/etc/nginx/waf/nac-logconfs/default-logconf",
8306+
ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf"},
82768307
},
82778308
expected: &validationResults{
82788309
isError: true,
@@ -8306,7 +8337,7 @@ func TestAddWafConfig(t *testing.T) {
83068337
wafConfig: &version2.WAF{
83078338
ApPolicy: "/etc/nginx/waf/nac-policies/ns1-dataguard-alarm",
83088339
ApSecurityLogEnable: true,
8309-
ApLogConf: "/etc/nginx/waf/nac-logconfs/ns2-logconf",
8340+
ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/ns2-logconf"},
83108341
},
83118342
expected: &validationResults{},
83128343
msg: "valid waf config, cross ns reference",

internal/k8s/controller.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2786,19 +2786,37 @@ func (lbc *LoadBalancerController) addWAFPolicyRefs(
27862786
apPolRef[apPolKey] = apPolicy
27872787
}
27882788

2789-
if pol.Spec.WAF.SecurityLog != nil && pol.Spec.WAF.SecurityLog.ApLogConf != "" {
2790-
logConfKey := pol.Spec.WAF.SecurityLog.ApLogConf
2791-
if !strings.Contains(pol.Spec.WAF.SecurityLog.ApLogConf, "/") {
2792-
logConfKey = fmt.Sprintf("%v/%v", pol.Namespace, logConfKey)
2793-
}
2789+
if pol.Spec.WAF.SecurityLog != nil && pol.Spec.WAF.SecurityLogs == nil {
2790+
if pol.Spec.WAF.SecurityLog.ApLogConf != "" {
2791+
logConfKey := pol.Spec.WAF.SecurityLog.ApLogConf
2792+
if !strings.Contains(pol.Spec.WAF.SecurityLog.ApLogConf, "/") {
2793+
logConfKey = fmt.Sprintf("%v/%v", pol.Namespace, logConfKey)
2794+
}
27942795

2795-
logConf, err := lbc.appProtectConfiguration.GetAppResource(appprotect.LogConfGVK.Kind, logConfKey)
2796-
if err != nil {
2797-
return fmt.Errorf("WAF policy %q is invalid: %w", logConfKey, err)
2796+
logConf, err := lbc.appProtectConfiguration.GetAppResource(appprotect.LogConfGVK.Kind, logConfKey)
2797+
if err != nil {
2798+
return fmt.Errorf("WAF policy %q is invalid: %w", logConfKey, err)
2799+
}
2800+
logConfRef[logConfKey] = logConf
27982801
}
2799-
logConfRef[logConfKey] = logConf
28002802
}
28012803

2804+
if pol.Spec.WAF.SecurityLogs != nil {
2805+
for _, SecLog := range pol.Spec.WAF.SecurityLogs {
2806+
if SecLog.ApLogConf != "" {
2807+
logConfKey := SecLog.ApLogConf
2808+
if !strings.Contains(SecLog.ApLogConf, "/") {
2809+
logConfKey = fmt.Sprintf("%v/%v", pol.Namespace, logConfKey)
2810+
}
2811+
2812+
logConf, err := lbc.appProtectConfiguration.GetAppResource(appprotect.LogConfGVK.Kind, logConfKey)
2813+
if err != nil {
2814+
return fmt.Errorf("WAF policy %q is invalid: %w", logConfKey, err)
2815+
}
2816+
logConfRef[logConfKey] = logConf
2817+
}
2818+
}
2819+
}
28022820
}
28032821
return nil
28042822
}
@@ -2846,6 +2864,13 @@ func getWAFPoliciesForAppProtectLogConf(pols []*conf_v1.Policy, key string) []*c
28462864
if pol.Spec.WAF != nil && pol.Spec.WAF.SecurityLog != nil && isMatchingResourceRef(pol.Namespace, pol.Spec.WAF.SecurityLog.ApLogConf, key) {
28472865
policies = append(policies, pol)
28482866
}
2867+
if pol.Spec.WAF != nil && pol.Spec.WAF.SecurityLogs != nil {
2868+
for _, logConf := range pol.Spec.WAF.SecurityLogs {
2869+
if isMatchingResourceRef(pol.Namespace, logConf.ApLogConf, key) {
2870+
policies = append(policies, pol)
2871+
}
2872+
}
2873+
}
28492874
}
28502875

28512876
return policies

0 commit comments

Comments
 (0)
0