Skip to content

Commit 7b4e4e2

Browse files
authored
Enable security features by default (#11819)
1 parent b795512 commit 7b4e4e2

28 files changed

+103
-262
lines changed

.github/workflows/ci.yaml

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ jobs:
258258
259259
strategy:
260260
matrix:
261-
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
261+
k8s: [v1.28.13, v1.29.8, v1.30.4, v1.31.0]
262262

263263
steps:
264264
- name: Checkout
@@ -309,26 +309,11 @@ jobs:
309309
(needs.changes.outputs.go == 'true') || (needs.changes.outputs.baseimage == 'true') || ${{ github.event.workflow_dispatch.run_e2e == 'true' }}
310310
strategy:
311311
matrix:
312-
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
312+
k8s: [v1.28.13, v1.29.8, v1.30.4, v1.31.0]
313313
uses: ./.github/workflows/zz-tmpl-k8s-e2e.yaml
314314
with:
315315
k8s-version: ${{ matrix.k8s }}
316316

317-
kubernetes-validations:
318-
name: Kubernetes with Validations
319-
needs:
320-
- changes
321-
- build
322-
if: |
323-
(needs.changes.outputs.go == 'true') || (needs.changes.outputs.baseimage == 'true') || ${{ github.event.workflow_dispatch.run_e2e == 'true' }}
324-
strategy:
325-
matrix:
326-
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
327-
uses: ./.github/workflows/zz-tmpl-k8s-e2e.yaml
328-
with:
329-
k8s-version: ${{ matrix.k8s }}
330-
variation: "VALIDATIONS"
331-
332317
kubernetes-chroot:
333318
name: Kubernetes chroot
334319
needs:
@@ -338,7 +323,7 @@ jobs:
338323
(needs.changes.outputs.go == 'true') || (needs.changes.outputs.baseimage == 'true') || ${{ github.event.workflow_dispatch.run_e2e == 'true' }}
339324
strategy:
340325
matrix:
341-
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
326+
k8s: [v1.28.13, v1.29.8, v1.30.4, v1.31.0]
342327
uses: ./.github/workflows/zz-tmpl-k8s-e2e.yaml
343328
with:
344329
k8s-version: ${{ matrix.k8s }}

.github/workflows/zz-tmpl-k8s-e2e.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ jobs:
4343
SKIP_CLUSTER_CREATION: true
4444
SKIP_INGRESS_IMAGE_CREATION: true
4545
SKIP_E2E_IMAGE_CREATION: true
46-
ENABLE_VALIDATIONS: ${{ inputs.variation == 'VALIDATIONS' }}
4746
IS_CHROOT: ${{ inputs.variation == 'CHROOT' }}
4847
run: |
4948
kind get kubeconfig > $HOME/.kube/kind-config-kind

charts/ingress-nginx/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
304304
| controller.dnsPolicy | string | `"ClusterFirst"` | Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. |
305305
| controller.electionID | string | `""` | Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader' |
306306
| controller.electionTTL | string | `""` | Duration a leader election is valid before it's getting re-elected, e.g. `15s`, `10m` or `1h`. (Default: 30s) |
307-
| controller.enableAnnotationValidations | bool | `false` | |
307+
| controller.enableAnnotationValidations | bool | `true` | |
308308
| controller.enableMimalloc | bool | `true` | Enable mimalloc as a drop-in replacement for malloc. # ref: https://github.com/microsoft/mimalloc # |
309309
| controller.enableTopologyAwareRouting | bool | `false` | This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-mode="auto" Defaults to false |
310310
| controller.existingPsp | string | `""` | Use an existing PSP instead of creating one |

charts/ingress-nginx/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ commonLabels: {}
1717

1818
controller:
1919
name: controller
20-
enableAnnotationValidations: false
20+
enableAnnotationValidations: true
2121
image:
2222
## Keep false as default for now!
2323
chroot: false

docs/user-guide/cli-arguments.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ They are set in the container spec of the `ingress-nginx-controller` Deployment
1515
| `--default-backend-service` | Service used to serve HTTP requests not matching any known server name (catch-all). Takes the form "namespace/name". The controller configures NGINX to forward requests to the first port of this Service. |
1616
| `--default-server-port` | Port to use for exposing the default server (catch-all). (default 8181) |
1717
| `--default-ssl-certificate` | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". |
18-
| `--enable-annotation-validation` | If true, will enable the annotation validation feature. This value will be defaulted to true on a future release. |
18+
| `--enable-annotation-validation` | If true, will enable the annotation validation feature. Defaults to true |
1919
| `--disable-catch-all` | Disable support for catch-all Ingresses. (default false) |
2020
| `--disable-full-test` | Disable full test of all merged ingresses at the admission stage and tests the template of the ingress being created or updated (full test of all ingresses is enabled by default). |
2121
| `--disable-svc-external-name` | Disable support for Services of type ExternalName. (default false) |

internal/ingress/controller/config/config.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -776,10 +776,10 @@ func NewDefault() Configuration {
776776

777777
cfg := Configuration{
778778
AllowSnippetAnnotations: false,
779-
AllowCrossNamespaceResources: true,
779+
AllowCrossNamespaceResources: false,
780780
AllowBackendServerHeader: false,
781781
AnnotationValueWordBlocklist: "",
782-
AnnotationsRiskLevel: "Critical",
782+
AnnotationsRiskLevel: "High",
783783
AccessLogPath: "/var/log/nginx/access.log",
784784
AccessLogParams: "",
785785
EnableAccessLogForDefaultBackend: false,
@@ -924,7 +924,7 @@ func NewDefault() Configuration {
924924
GlobalRateLimitMemcachedPoolSize: 50,
925925
GlobalRateLimitStatusCode: 429,
926926
DebugConnections: []string{},
927-
StrictValidatePathType: false, // TODO: This will be true in future releases
927+
StrictValidatePathType: true,
928928
GRPCBufferSizeKb: 0,
929929
}
930930

pkg/flags/flags.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Requires the update-status parameter.`)
158158
annotationsPrefix = flags.String("annotations-prefix", parser.DefaultAnnotationsPrefix,
159159
`Prefix of the Ingress annotations specific to the NGINX controller.`)
160160

161-
enableAnnotationValidation = flags.Bool("enable-annotation-validation", false,
161+
enableAnnotationValidation = flags.Bool("enable-annotation-validation", true,
162162
`If true, will enable the annotation validation feature. This value will be defaulted to true on a future release`)
163163

164164
enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", false,

test/e2e/admission/admission.go

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
127127
})
128128

129129
ginkgo.It("should return an error if there is an error validating the ingress definition", func() {
130-
f.SetNginxConfigMapData(map[string]string{
131-
"allow-snippet-annotations": "true",
132-
})
133-
defer func() {
134-
f.SetNginxConfigMapData(map[string]string{
135-
"allow-snippet-annotations": "false",
136-
})
137-
}()
130+
disableSnippet := f.AllowSnippetConfiguration()
131+
defer disableSnippet()
138132

139133
host := admissionTestHost
140134

@@ -241,14 +235,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
241235
})
242236

243237
ginkgo.It("should return an error if the Ingress V1 definition contains invalid annotations", func() {
244-
f.SetNginxConfigMapData(map[string]string{
245-
"allow-snippet-annotations": "true",
246-
})
247-
defer func() {
248-
f.SetNginxConfigMapData(map[string]string{
249-
"allow-snippet-annotations": "false",
250-
})
251-
}()
238+
disableSnippet := f.AllowSnippetConfiguration()
239+
defer disableSnippet()
252240

253241
out, err := createIngress(f.Namespace, invalidV1Ingress)
254242
assert.Empty(ginkgo.GinkgoT(), out)
@@ -261,14 +249,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
261249
})
262250

263251
ginkgo.It("should not return an error for an invalid Ingress when it has unknown class", func() {
264-
f.SetNginxConfigMapData(map[string]string{
265-
"allow-snippet-annotations": "true",
266-
})
267-
defer func() {
268-
f.SetNginxConfigMapData(map[string]string{
269-
"allow-snippet-annotations": "false",
270-
})
271-
}()
252+
disableSnippet := f.AllowSnippetConfiguration()
253+
defer disableSnippet()
272254
out, err := createIngress(f.Namespace, invalidV1IngressWithOtherClass)
273255
assert.Equal(ginkgo.GinkgoT(), "ingress.networking.k8s.io/extensions-invalid-other created\n", out)
274256
assert.Nil(ginkgo.GinkgoT(), err, "creating an invalid ingress with unknown class using kubectl")

test/e2e/annotations/auth.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,8 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
277277
"nginx.ingress.kubernetes.io/auth-snippet": `
278278
proxy_set_header My-Custom-Header 42;`,
279279
}
280-
f.SetNginxConfigMapData(map[string]string{
281-
"allow-snippet-annotations": "true",
282-
})
283-
defer func() {
284-
f.SetNginxConfigMapData(map[string]string{
285-
"allow-snippet-annotations": "false",
286-
})
287-
}()
280+
disableSnippet := f.AllowSnippetConfiguration()
281+
defer disableSnippet()
288282

289283
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
290284
f.EnsureIngress(ing)
@@ -297,15 +291,8 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
297291

298292
ginkgo.It(`should not set snippet "proxy_set_header My-Custom-Header 42;" when external auth is not configured`, func() {
299293
host := authHost
300-
301-
f.SetNginxConfigMapData(map[string]string{
302-
"allow-snippet-annotations": "true",
303-
})
304-
defer func() {
305-
f.SetNginxConfigMapData(map[string]string{
306-
"allow-snippet-annotations": "false",
307-
})
308-
}()
294+
disableSnippet := f.AllowSnippetConfiguration()
295+
defer disableSnippet()
309296

310297
annotations := map[string]string{
311298
"nginx.ingress.kubernetes.io/auth-snippet": `

test/e2e/annotations/fromtowwwredirect.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,8 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() {
6262
})
6363

6464
ginkgo.It("should redirect from www HTTPS to HTTPS", func() {
65-
f.SetNginxConfigMapData(map[string]string{
66-
"allow-snippet-annotations": "true",
67-
})
68-
defer func() {
69-
f.SetNginxConfigMapData(map[string]string{
70-
"allow-snippet-annotations": "false",
71-
})
72-
}()
65+
disableSnippet := f.AllowSnippetConfiguration()
66+
defer disableSnippet()
7367

7468
ginkgo.By("setting up server for redirect from www")
7569

test/e2e/annotations/grpc.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,8 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
193193
ginkgo.It("should return OK for service with backend protocol GRPCS", func() {
194194
f.NewGRPCBinDeployment()
195195

196-
f.SetNginxConfigMapData(map[string]string{
197-
"allow-snippet-annotations": "true",
198-
})
199-
defer func() {
200-
f.SetNginxConfigMapData(map[string]string{
201-
"allow-snippet-annotations": "false",
202-
})
203-
}()
196+
disableSnippet := f.AllowSnippetConfiguration()
197+
defer disableSnippet()
204198

205199
host := echoHost
206200

test/e2e/annotations/modsecurity/modsecurity.go

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
100100
})
101101

102102
ginkgo.It("should enable modsecurity with snippet", func() {
103-
f.SetNginxConfigMapData(map[string]string{
104-
"allow-snippet-annotations": "true",
105-
})
106-
defer func() {
107-
f.SetNginxConfigMapData(map[string]string{
108-
"allow-snippet-annotations": "false",
109-
})
110-
}()
103+
disableSnippet := f.AllowSnippetConfiguration()
104+
defer disableSnippet()
111105

112106
host := modSecurityFooHost
113107
nameSpace := f.Namespace
@@ -173,14 +167,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
173167
})
174168

175169
ginkgo.It("should enable modsecurity with snippet and block requests", func() {
176-
f.SetNginxConfigMapData(map[string]string{
177-
"allow-snippet-annotations": "true",
178-
})
179-
defer func() {
180-
f.SetNginxConfigMapData(map[string]string{
181-
"allow-snippet-annotations": "false",
182-
})
183-
}()
170+
disableSnippet := f.AllowSnippetConfiguration()
171+
defer disableSnippet()
184172

185173
host := modSecurityFooHost
186174
nameSpace := f.Namespace
@@ -212,14 +200,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
212200
})
213201

214202
ginkgo.It("should enable modsecurity globally and with modsecurity-snippet block requests", func() {
215-
f.SetNginxConfigMapData(map[string]string{
216-
"allow-snippet-annotations": "true",
217-
})
218-
defer func() {
219-
f.SetNginxConfigMapData(map[string]string{
220-
"allow-snippet-annotations": "false",
221-
})
222-
}()
203+
disableSnippet := f.AllowSnippetConfiguration()
204+
defer disableSnippet()
223205

224206
host := modSecurityFooHost
225207
nameSpace := f.Namespace
@@ -251,16 +233,11 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
251233
})
252234

253235
ginkgo.It("should enable modsecurity when enable-owasp-modsecurity-crs is set to true", func() {
254-
f.SetNginxConfigMapData(map[string]string{
255-
"allow-snippet-annotations": "true",
256-
"enable-modsecurity": "true",
257-
"enable-owasp-modsecurity-crs": "true",
258-
})
259-
defer func() {
260-
f.SetNginxConfigMapData(map[string]string{
261-
"allow-snippet-annotations": "false",
262-
})
263-
}()
236+
disableSnippet := f.AllowSnippetConfiguration()
237+
defer disableSnippet()
238+
239+
f.UpdateNginxConfigMapData("enable-modsecurity", "true")
240+
f.UpdateNginxConfigMapData("enable-owasp-modsecurity-crs", "true")
264241

265242
host := modSecurityFooHost
266243
nameSpace := f.Namespace
@@ -290,6 +267,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
290267
})
291268

292269
ginkgo.It("should enable modsecurity through the config map", func() {
270+
disableSnippet := f.AllowSnippetConfiguration()
271+
defer disableSnippet()
293272
host := modSecurityFooHost
294273
nameSpace := f.Namespace
295274

@@ -310,17 +289,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
310289
f.EnsureIngress(ing)
311290

312291
expectedComment := "SecRuleEngine On"
313-
f.SetNginxConfigMapData(map[string]string{
314-
"allow-snippet-annotations": "true",
315-
"enable-modsecurity": "true",
316-
"enable-owasp-modsecurity-crs": "true",
317-
"modsecurity-snippet": expectedComment,
318-
})
319-
defer func() {
320-
f.SetNginxConfigMapData(map[string]string{
321-
"allow-snippet-annotations": "false",
322-
})
323-
}()
292+
f.UpdateNginxConfigMapData("enable-modsecurity", "true")
293+
f.UpdateNginxConfigMapData("enable-owasp-modsecurity-crs", "true")
294+
f.UpdateNginxConfigMapData("modsecurity-snippet", expectedComment)
324295

325296
f.WaitForNginxServer(host,
326297
func(server string) bool {
@@ -339,6 +310,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
339310
host := modSecurityFooHost
340311
nameSpace := f.Namespace
341312

313+
f.UpdateNginxConfigMapData("annotations-risk-level", "Critical") // To enable snippet configurations
314+
defer f.UpdateNginxConfigMapData("annotations-risk-level", "High")
315+
342316
snippet := `SecRequestBodyAccess On
343317
SecAuditEngine RelevantOnly
344318
SecAuditLogParts ABIJDEFHZ
@@ -378,14 +352,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
378352
})
379353

380354
ginkgo.It("should disable default modsecurity conf setting when modsecurity-snippet is specified", func() {
381-
f.SetNginxConfigMapData(map[string]string{
382-
"allow-snippet-annotations": "true",
383-
})
384-
defer func() {
385-
f.SetNginxConfigMapData(map[string]string{
386-
"allow-snippet-annotations": "false",
387-
})
388-
}()
355+
disableSnippet := f.AllowSnippetConfiguration()
356+
defer disableSnippet()
357+
389358
host := modSecurityFooHost
390359
nameSpace := f.Namespace
391360

0 commit comments

Comments
 (0)