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

Skip to content

Commit 79b8c9c

Browse files
Rafal Wegrzyckirafwegv
authored andcommitted
Add handling of mutiple log destinations
1 parent 8b53e1e commit 79b8c9c

File tree

20 files changed

+466
-56
lines changed

20 files changed

+466
-56
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
@@ -355,17 +355,20 @@ For `kubectl get` and similar commands, you can also use the short name `pol` in
355355

356356
The WAF policy configures NGINX Plus to secure client requests using App Protect policies.
357357

358-
For example, the following policy will enable the referenced APPolicy and APLogConf with the configured log destination:
358+
For example, the following policy will enable the referenced APPolicy. You can configure multiple APLogConfs with log destinations:
359359
```yaml
360360
waf:
361361
enable: true
362362
apPolicy: "default/dataguard-alarm"
363-
securityLog:
364-
enable: true
363+
securityLogs:
364+
- enable: true
365365
apLogConf: "default/logconf"
366366
logDest: "syslog:server=syslog-svc.default:514"
367+
- enable: true
368+
apLogConf: "default/logconf"
369+
logDest: "syslog:server=syslog-svc-secondary.default:514"
367370
```
368-
371+
> Note: The field `waf.securityLog` is deprecated and will be removed in future releases.It will be ignored if `waf.securityLogs` is populated.
369372
> Note: The feature is implemented using the NGINX Plus [NGINX App Protect Module](https://docs.nginx.com/nginx-app-protect/configuration/).
370373

371374
{{% 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/ingress.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ type MergeableIngresses struct {
7676
}
7777

7878
func generateNginxCfg(ingEx *IngressEx, apResources *AppProtectResources, dosResource *appProtectDosResource, isMinion bool,
79-
baseCfgParams *ConfigParams, isPlus bool, isResolverConfigured bool, staticParams *StaticConfigParams, isWildcardEnabled bool) (version1.IngressNginxConfig, Warnings) {
79+
baseCfgParams *ConfigParams, isPlus bool, isResolverConfigured bool, staticParams *StaticConfigParams, isWildcardEnabled bool,
80+
) (version1.IngressNginxConfig, Warnings) {
8081
hasAppProtect := staticParams.MainAppProtectLoadModule
8182
hasAppProtectDos := staticParams.MainAppProtectDosLoadModule
8283

@@ -290,7 +291,8 @@ func generateNginxCfg(ingEx *IngressEx, apResources *AppProtectResources, dosRes
290291
}
291292

292293
func generateJWTConfig(owner runtime.Object, secretRefs map[string]*secrets.SecretReference, cfgParams *ConfigParams,
293-
redirectLocationName string) (*version1.JWTAuth, *version1.JWTRedirectLocation, Warnings) {
294+
redirectLocationName string,
295+
) (*version1.JWTAuth, *version1.JWTRedirectLocation, Warnings) {
294296
warnings := newWarnings()
295297

296298
secretRef := secretRefs[cfgParams.JWTKey]
@@ -326,7 +328,8 @@ func generateJWTConfig(owner runtime.Object, secretRefs map[string]*secrets.Secr
326328
}
327329

328330
func addSSLConfig(server *version1.Server, owner runtime.Object, host string, ingressTLS []networking.IngressTLS,
329-
secretRefs map[string]*secrets.SecretReference, isWildcardEnabled bool) Warnings {
331+
secretRefs map[string]*secrets.SecretReference, isWildcardEnabled bool,
332+
) Warnings {
330333
warnings := newWarnings()
331334

332335
var tlsEnabled bool
@@ -427,7 +430,8 @@ func upstreamRequiresQueue(name string, ingEx *IngressEx, cfg *ConfigParams) (n
427430
}
428431

429432
func createUpstream(ingEx *IngressEx, name string, backend *networking.IngressBackend, stickyCookie string, cfg *ConfigParams,
430-
isPlus bool, isResolverConfigured bool, isLatencyMetricsEnabled bool) version1.Upstream {
433+
isPlus bool, isResolverConfigured bool, isLatencyMetricsEnabled bool,
434+
) version1.Upstream {
431435
var ups version1.Upstream
432436
labels := version1.UpstreamLabels{
433437
Service: backend.Service.Name,
@@ -534,8 +538,8 @@ func upstreamMapToSlice(upstreams map[string]version1.Upstream) []version1.Upstr
534538

535539
func generateNginxCfgForMergeableIngresses(mergeableIngs *MergeableIngresses, apResources *AppProtectResources,
536540
dosResource *appProtectDosResource, baseCfgParams *ConfigParams, isPlus bool, isResolverConfigured bool,
537-
staticParams *StaticConfigParams, isWildcardEnabled bool) (version1.IngressNginxConfig, Warnings) {
538-
541+
staticParams *StaticConfigParams, isWildcardEnabled bool,
542+
) (version1.IngressNginxConfig, Warnings) {
539543
var masterServer version1.Server
540544
var locations []version1.Location
541545
var upstreams []version1.Upstream

internal/configs/version1/templates_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ var (
3939
)
4040

4141
var ingCfg = IngressNginxConfig{
42-
4342
Servers: []Server{
4443
{
4544
Name: "test.example.com",

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: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,9 @@ server {
191191

192192
{{ if .ApSecurityLogEnable }}
193193
app_protect_security_log_enable on;
194-
app_protect_security_log {{ .ApLogConf }};
194+
{{ range $logconf := .ApLogConf }}
195+
app_protect_security_log {{ $logconf }};
196+
{{ end }}
195197
{{ end }}
196198
{{ end }}
197199

@@ -370,7 +372,9 @@ server {
370372

371373
{{ if .ApSecurityLogEnable }}
372374
app_protect_security_log_enable on;
373-
app_protect_security_log {{ .ApLogConf }};
375+
{{ range $logconf := .ApLogConf }}
376+
app_protect_security_log {{ $logconf }};
377+
{{ end }}
374378
{{ end }}
375379
{{ end }}
376380

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: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,8 @@ func (p *policiesCfg) addWAFConfig(
10411041
}
10421042
}
10431043

1044-
if waf.SecurityLog != nil {
1044+
if waf.SecurityLog != nil && waf.SecurityLogs == nil {
1045+
glog.V(2).Info("the field securityLog is deprecated nad will be removed in future releases. Use field securityLogs instead")
10451046
p.WAF.ApSecurityLogEnable = true
10461047

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

10531054
if logConfPath, ok := apResources.LogConfs[logConfKey]; ok {
10541055
logDest := generateString(waf.SecurityLog.LogDest, "syslog:server=localhost:514")
1055-
p.WAF.ApLogConf = fmt.Sprintf("%s %s", logConfPath, logDest)
1056+
p.WAF.ApLogConf = []string{fmt.Sprintf("%s %s", logConfPath, logDest)}
10561057
} else {
10571058
res.addWarningf("WAF policy %s references an invalid or non-existing log config %s", polKey, logConfKey)
10581059
res.isError = true
10591060
}
10601061
}
10611062

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+
}
10621081
return res
10631082
}
10641083

@@ -1575,7 +1594,8 @@ type errorPageDetails struct {
15751594
func generateLocation(path string, upstreamName string, upstream conf_v1.Upstream, action *conf_v1.Action,
15761595
cfgParams *ConfigParams, errorPages errorPageDetails, internal bool, proxySSLName string,
15771596
originalPath string, locSnippets string, enableSnippets bool, retLocIndex int, isVSR bool, vsrName string,
1578-
vsrNamespace string, vscWarnings Warnings) (version2.Location, *version2.ReturnLocation) {
1597+
vsrNamespace string, vscWarnings Warnings,
1598+
) (version2.Location, *version2.ReturnLocation) {
15791599
locationSnippets := generateSnippets(enableSnippets, locSnippets, cfgParams.LocationSnippets)
15801600

15811601
if action.Redirect != nil {
@@ -1674,7 +1694,8 @@ func generateProxyAddHeaders(proxy *conf_v1.ActionProxy) []version2.AddHeader {
16741694

16751695
func generateLocationForProxying(path string, upstreamName string, upstream conf_v1.Upstream,
16761696
cfgParams *ConfigParams, errorPages []conf_v1.ErrorPage, internal bool, errPageIndex int,
1677-
proxySSLName string, proxy *conf_v1.ActionProxy, originalPath string, locationSnippets []string, isVSR bool, vsrName string, vsrNamespace string) version2.Location {
1697+
proxySSLName string, proxy *conf_v1.ActionProxy, originalPath string, locationSnippets []string, isVSR bool, vsrName string, vsrNamespace string,
1698+
) version2.Location {
16781699
return version2.Location{
16791700
Path: generatePath(path),
16801701
Internal: internal,
@@ -1741,7 +1762,8 @@ func generateLocationForRedirect(
17411762
}
17421763

17431764
func generateLocationForReturn(path string, locationSnippets []string, actionReturn *conf_v1.ActionReturn,
1744-
retLocIndex int) (version2.Location, *version2.ReturnLocation) {
1765+
retLocIndex int,
1766+
) (version2.Location, *version2.ReturnLocation) {
17451767
defaultType := actionReturn.Type
17461768
if defaultType == "" {
17471769
defaultType = "text/plain"
@@ -1873,7 +1895,8 @@ func generateDefaultSplitsConfig(
18731895

18741896
func generateMatchesConfig(route conf_v1.Route, upstreamNamer *upstreamNamer, crUpstreams map[string]conf_v1.Upstream,
18751897
variableNamer *variableNamer, index int, scIndex int, cfgParams *ConfigParams, errorPages errorPageDetails,
1876-
locSnippets string, enableSnippets bool, retLocIndex int, isVSR bool, vsrName string, vsrNamespace string, vscWarnings Warnings) routingCfg {
1898+
locSnippets string, enableSnippets bool, retLocIndex int, isVSR bool, vsrName string, vsrNamespace string, vscWarnings Warnings,
1899+
) routingCfg {
18771900
// Generate maps
18781901
var maps []version2.Map
18791902

@@ -2101,7 +2124,8 @@ func getNameForSourceForMatchesRouteMapFromCondition(condition conf_v1.Condition
21012124
}
21022125

21032126
func (vsc *virtualServerConfigurator) generateSSLConfig(owner runtime.Object, tls *conf_v1.TLS, namespace string,
2104-
secretRefs map[string]*secrets.SecretReference, cfgParams *ConfigParams) *version2.SSL {
2127+
secretRefs map[string]*secrets.SecretReference, cfgParams *ConfigParams,
2128+
) *version2.SSL {
21052129
if tls == nil {
21062130
return nil
21072131
}

0 commit comments

Comments
 (0)
0