Enable security features by default (#11819)
This commit is contained in:
parent
b79551287e
commit
7b4e4e2fa1
28 changed files with 103 additions and 262 deletions
21
.github/workflows/ci.yaml
vendored
21
.github/workflows/ci.yaml
vendored
|
@ -258,7 +258,7 @@ jobs:
|
|||
|
||||
strategy:
|
||||
matrix:
|
||||
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
|
||||
k8s: [v1.28.13, v1.29.8, v1.30.4, v1.31.0]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -309,26 +309,11 @@ jobs:
|
|||
(needs.changes.outputs.go == 'true') || (needs.changes.outputs.baseimage == 'true') || ${{ github.event.workflow_dispatch.run_e2e == 'true' }}
|
||||
strategy:
|
||||
matrix:
|
||||
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
|
||||
k8s: [v1.28.13, v1.29.8, v1.30.4, v1.31.0]
|
||||
uses: ./.github/workflows/zz-tmpl-k8s-e2e.yaml
|
||||
with:
|
||||
k8s-version: ${{ matrix.k8s }}
|
||||
|
||||
kubernetes-validations:
|
||||
name: Kubernetes with Validations
|
||||
needs:
|
||||
- changes
|
||||
- build
|
||||
if: |
|
||||
(needs.changes.outputs.go == 'true') || (needs.changes.outputs.baseimage == 'true') || ${{ github.event.workflow_dispatch.run_e2e == 'true' }}
|
||||
strategy:
|
||||
matrix:
|
||||
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
|
||||
uses: ./.github/workflows/zz-tmpl-k8s-e2e.yaml
|
||||
with:
|
||||
k8s-version: ${{ matrix.k8s }}
|
||||
variation: "VALIDATIONS"
|
||||
|
||||
kubernetes-chroot:
|
||||
name: Kubernetes chroot
|
||||
needs:
|
||||
|
@ -338,7 +323,7 @@ jobs:
|
|||
(needs.changes.outputs.go == 'true') || (needs.changes.outputs.baseimage == 'true') || ${{ github.event.workflow_dispatch.run_e2e == 'true' }}
|
||||
strategy:
|
||||
matrix:
|
||||
k8s: [v1.26.15, v1.27.13, v1.28.9, v1.29.4, v1.30.0]
|
||||
k8s: [v1.28.13, v1.29.8, v1.30.4, v1.31.0]
|
||||
uses: ./.github/workflows/zz-tmpl-k8s-e2e.yaml
|
||||
with:
|
||||
k8s-version: ${{ matrix.k8s }}
|
||||
|
|
1
.github/workflows/zz-tmpl-k8s-e2e.yaml
vendored
1
.github/workflows/zz-tmpl-k8s-e2e.yaml
vendored
|
@ -43,7 +43,6 @@ jobs:
|
|||
SKIP_CLUSTER_CREATION: true
|
||||
SKIP_INGRESS_IMAGE_CREATION: true
|
||||
SKIP_E2E_IMAGE_CREATION: true
|
||||
ENABLE_VALIDATIONS: ${{ inputs.variation == 'VALIDATIONS' }}
|
||||
IS_CHROOT: ${{ inputs.variation == 'CHROOT' }}
|
||||
run: |
|
||||
kind get kubeconfig > $HOME/.kube/kind-config-kind
|
||||
|
|
|
@ -304,7 +304,7 @@ As of version `1.26.0` of this chart, by simply not providing any clusterIP valu
|
|||
| 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. |
|
||||
| controller.electionID | string | `""` | Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader' |
|
||||
| controller.electionTTL | string | `""` | Duration a leader election is valid before it's getting re-elected, e.g. `15s`, `10m` or `1h`. (Default: 30s) |
|
||||
| controller.enableAnnotationValidations | bool | `false` | |
|
||||
| controller.enableAnnotationValidations | bool | `true` | |
|
||||
| controller.enableMimalloc | bool | `true` | Enable mimalloc as a drop-in replacement for malloc. # ref: https://github.com/microsoft/mimalloc # |
|
||||
| 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 |
|
||||
| controller.existingPsp | string | `""` | Use an existing PSP instead of creating one |
|
||||
|
|
|
@ -17,7 +17,7 @@ commonLabels: {}
|
|||
|
||||
controller:
|
||||
name: controller
|
||||
enableAnnotationValidations: false
|
||||
enableAnnotationValidations: true
|
||||
image:
|
||||
## Keep false as default for now!
|
||||
chroot: false
|
||||
|
|
|
@ -15,7 +15,7 @@ They are set in the container spec of the `ingress-nginx-controller` Deployment
|
|||
| `--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. |
|
||||
| `--default-server-port` | Port to use for exposing the default server (catch-all). (default 8181) |
|
||||
| `--default-ssl-certificate` | Secret containing a SSL certificate to be used by the default HTTPS server (catch-all). Takes the form "namespace/name". |
|
||||
| `--enable-annotation-validation` | If true, will enable the annotation validation feature. This value will be defaulted to true on a future release. |
|
||||
| `--enable-annotation-validation` | If true, will enable the annotation validation feature. Defaults to true |
|
||||
| `--disable-catch-all` | Disable support for catch-all Ingresses. (default false) |
|
||||
| `--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). |
|
||||
| `--disable-svc-external-name` | Disable support for Services of type ExternalName. (default false) |
|
||||
|
|
|
@ -776,10 +776,10 @@ func NewDefault() Configuration {
|
|||
|
||||
cfg := Configuration{
|
||||
AllowSnippetAnnotations: false,
|
||||
AllowCrossNamespaceResources: true,
|
||||
AllowCrossNamespaceResources: false,
|
||||
AllowBackendServerHeader: false,
|
||||
AnnotationValueWordBlocklist: "",
|
||||
AnnotationsRiskLevel: "Critical",
|
||||
AnnotationsRiskLevel: "High",
|
||||
AccessLogPath: "/var/log/nginx/access.log",
|
||||
AccessLogParams: "",
|
||||
EnableAccessLogForDefaultBackend: false,
|
||||
|
@ -924,7 +924,7 @@ func NewDefault() Configuration {
|
|||
GlobalRateLimitMemcachedPoolSize: 50,
|
||||
GlobalRateLimitStatusCode: 429,
|
||||
DebugConnections: []string{},
|
||||
StrictValidatePathType: false, // TODO: This will be true in future releases
|
||||
StrictValidatePathType: true,
|
||||
GRPCBufferSizeKb: 0,
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ Requires the update-status parameter.`)
|
|||
annotationsPrefix = flags.String("annotations-prefix", parser.DefaultAnnotationsPrefix,
|
||||
`Prefix of the Ingress annotations specific to the NGINX controller.`)
|
||||
|
||||
enableAnnotationValidation = flags.Bool("enable-annotation-validation", false,
|
||||
enableAnnotationValidation = flags.Bool("enable-annotation-validation", true,
|
||||
`If true, will enable the annotation validation feature. This value will be defaulted to true on a future release`)
|
||||
|
||||
enableSSLChainCompletion = flags.Bool("enable-ssl-chain-completion", false,
|
||||
|
|
|
@ -127,14 +127,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should return an error if there is an error validating the ingress definition", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := admissionTestHost
|
||||
|
||||
|
@ -241,14 +235,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should return an error if the Ingress V1 definition contains invalid annotations", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
out, err := createIngress(f.Namespace, invalidV1Ingress)
|
||||
assert.Empty(ginkgo.GinkgoT(), out)
|
||||
|
@ -261,14 +249,8 @@ var _ = framework.IngressNginxDescribeSerial("[Admission] admission controller",
|
|||
})
|
||||
|
||||
ginkgo.It("should not return an error for an invalid Ingress when it has unknown class", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
out, err := createIngress(f.Namespace, invalidV1IngressWithOtherClass)
|
||||
assert.Equal(ginkgo.GinkgoT(), "ingress.networking.k8s.io/extensions-invalid-other created\n", out)
|
||||
assert.Nil(ginkgo.GinkgoT(), err, "creating an invalid ingress with unknown class using kubectl")
|
||||
|
|
|
@ -277,14 +277,8 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
"nginx.ingress.kubernetes.io/auth-snippet": `
|
||||
proxy_set_header My-Custom-Header 42;`,
|
||||
}
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
@ -297,15 +291,8 @@ var _ = framework.DescribeAnnotation("auth-*", func() {
|
|||
|
||||
ginkgo.It(`should not set snippet "proxy_set_header My-Custom-Header 42;" when external auth is not configured`, func() {
|
||||
host := authHost
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/auth-snippet": `
|
||||
|
|
|
@ -62,14 +62,8 @@ var _ = framework.DescribeAnnotation("from-to-www-redirect", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should redirect from www HTTPS to HTTPS", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
ginkgo.By("setting up server for redirect from www")
|
||||
|
||||
|
|
|
@ -193,14 +193,8 @@ var _ = framework.DescribeAnnotation("backend-protocol - GRPC", func() {
|
|||
ginkgo.It("should return OK for service with backend protocol GRPCS", func() {
|
||||
f.NewGRPCBinDeployment()
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := echoHost
|
||||
|
||||
|
|
|
@ -100,14 +100,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity with snippet", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
@ -173,14 +167,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity with snippet and block requests", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
@ -212,14 +200,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity globally and with modsecurity-snippet block requests", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
@ -251,16 +233,11 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity when enable-owasp-modsecurity-crs is set to true", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"enable-modsecurity": "true",
|
||||
"enable-owasp-modsecurity-crs": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
f.UpdateNginxConfigMapData("enable-modsecurity", "true")
|
||||
f.UpdateNginxConfigMapData("enable-owasp-modsecurity-crs", "true")
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
@ -290,6 +267,8 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity through the config map", func() {
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
|
@ -310,17 +289,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
f.EnsureIngress(ing)
|
||||
|
||||
expectedComment := "SecRuleEngine On"
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"enable-modsecurity": "true",
|
||||
"enable-owasp-modsecurity-crs": "true",
|
||||
"modsecurity-snippet": expectedComment,
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
f.UpdateNginxConfigMapData("enable-modsecurity", "true")
|
||||
f.UpdateNginxConfigMapData("enable-owasp-modsecurity-crs", "true")
|
||||
f.UpdateNginxConfigMapData("modsecurity-snippet", expectedComment)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
|
@ -339,6 +310,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
f.UpdateNginxConfigMapData("annotations-risk-level", "Critical") // To enable snippet configurations
|
||||
defer f.UpdateNginxConfigMapData("annotations-risk-level", "High")
|
||||
|
||||
snippet := `SecRequestBodyAccess On
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
|
@ -378,14 +352,9 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should disable default modsecurity conf setting when modsecurity-snippet is specified", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := modSecurityFooHost
|
||||
nameSpace := f.Namespace
|
||||
|
||||
|
|
|
@ -33,14 +33,8 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`add valid directives to server via server snippet`, func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := "serversnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
|
@ -68,14 +62,8 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
})
|
||||
|
||||
ginkgo.It(`drops server snippet if disabled by the administrator`, func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
f.UpdateNginxConfigMapData("annotations-risk-level", "Critical") // To enable snippet configurations
|
||||
defer f.UpdateNginxConfigMapData("annotations-risk-level", "High")
|
||||
|
||||
host := "noserversnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
|
@ -85,11 +73,6 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.UpdateNginxConfigMapData("allow-snippet-annotations", "false")
|
||||
defer func() {
|
||||
// Return to the original value
|
||||
f.UpdateNginxConfigMapData("allow-snippet-annotations", "true")
|
||||
}()
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
f.EnsureIngress(ing)
|
||||
|
|
|
@ -33,15 +33,8 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
|
|||
|
||||
ginkgo.It("set snippet more_set_headers in all locations", func() {
|
||||
host := "configurationsnippet.foo.com"
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`,
|
||||
|
@ -71,6 +64,8 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("drops snippet more_set_header in all locations if disabled by admin", func() {
|
||||
f.UpdateNginxConfigMapData("annotations-risk-level", "Critical") // To enable snippet configurations
|
||||
defer f.UpdateNginxConfigMapData("annotations-risk-level", "High")
|
||||
host := "noconfigurationsnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Foo1: Bar1";`,
|
||||
|
|
|
@ -39,14 +39,8 @@ var _ = framework.DescribeSetting("stream-snippet", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should add value of stream-snippet to nginx config", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := "foo.com"
|
||||
|
||||
|
|
|
@ -117,11 +117,7 @@ func (f *Framework) newIngressController(namespace, namespaceOverlay string) err
|
|||
isChroot = "false"
|
||||
}
|
||||
|
||||
enableAnnotationValidations, ok := os.LookupEnv("ENABLE_VALIDATIONS")
|
||||
if !ok {
|
||||
enableAnnotationValidations = "false"
|
||||
}
|
||||
cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay, isChroot, enableAnnotationValidations)
|
||||
cmd := exec.Command("./wait-for-nginx.sh", namespace, namespaceOverlay, isChroot)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unexpected error waiting for ingress controller deployment: %v.\nLogs:\n%v", err, string(out))
|
||||
|
|
|
@ -383,6 +383,20 @@ func (f *Framework) SetNginxConfigMapData(cmData map[string]string) {
|
|||
f.WaitForReload(fn)
|
||||
}
|
||||
|
||||
// SetNginxConfigMapData sets ingress-nginx's nginx-ingress-controller configMap data
|
||||
func (f *Framework) AllowSnippetConfiguration() func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"annotations-risk-level": "Critical", // To enable snippet configurations
|
||||
})
|
||||
return func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
"annotations-risk-level": "High",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// CreateConfigMap creates a new configmap in the current namespace
|
||||
func (f *Framework) CreateConfigMap(name string, data map[string]string) {
|
||||
_, err := f.KubeClientSet.CoreV1().ConfigMaps(f.Namespace).Create(context.TODO(), &v1.ConfigMap{
|
||||
|
|
|
@ -36,14 +36,8 @@ var _ = framework.IngressNginxDescribe("single ingress - multiple hosts", func()
|
|||
})
|
||||
|
||||
ginkgo.It("should set the correct $service_name NGINX variable", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_input_headers "service-name: $service_name";`,
|
||||
|
|
|
@ -35,14 +35,8 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] exact", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should choose exact location for /exact", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := "exact.path"
|
||||
|
||||
|
|
|
@ -37,14 +37,8 @@ var _ = framework.IngressNginxDescribe("[Ingress] [PathType] mix Exact and Prefi
|
|||
exactPathType := networking.PathTypeExact
|
||||
|
||||
ginkgo.It("should choose the correct location", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := "mixed.path"
|
||||
|
||||
|
|
|
@ -78,7 +78,6 @@ kubectl run --rm \
|
|||
--env="E2E_NODES=${E2E_NODES}" \
|
||||
--env="FOCUS=${FOCUS}" \
|
||||
--env="IS_CHROOT=${IS_CHROOT:-false}"\
|
||||
--env="ENABLE_VALIDATIONS=${ENABLE_VALIDATIONS:-false}"\
|
||||
--env="SKIP_OPENTELEMETRY_TESTS=${SKIP_OPENTELEMETRY_TESTS:-false}"\
|
||||
--env="E2E_CHECK_LEAKS=${E2E_CHECK_LEAKS}" \
|
||||
--env="NGINX_BASE_IMAGE=${NGINX_BASE_IMAGE}" \
|
||||
|
|
|
@ -39,7 +39,6 @@ fi
|
|||
|
||||
KIND_LOG_LEVEL="1"
|
||||
IS_CHROOT="${IS_CHROOT:-false}"
|
||||
ENABLE_VALIDATIONS="${ENABLE_VALIDATIONS:-false}"
|
||||
export KIND_CLUSTER_NAME=${KIND_CLUSTER_NAME:-ingress-nginx-dev}
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
# Use 1.0.0-dev to make sure we use the latest configuration in the helm template
|
||||
|
|
|
@ -34,14 +34,8 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is an invalid character in some annotation", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
host := "invalid-value-test"
|
||||
|
||||
annotations := map[string]string{
|
||||
|
@ -50,7 +44,6 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.UpdateNginxConfigMapData("allow-snippet-annotations", "true")
|
||||
f.UpdateNginxConfigMapData("annotation-value-word-blocklist", "something_forbidden,otherthing_forbidden,{")
|
||||
|
||||
f.EnsureIngress(ing)
|
||||
|
@ -73,14 +66,8 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a forbidden word in some annotation", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
host := "forbidden-value-test"
|
||||
|
||||
|
@ -93,7 +80,6 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.UpdateNginxConfigMapData("allow-snippet-annotations", "true")
|
||||
f.UpdateNginxConfigMapData("annotation-value-word-blocklist", "something_forbidden,otherthing_forbidden,content_by_lua_block")
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
@ -117,14 +103,9 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should allow an ingress if there is a default blocklist config in place", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
hostValid := "custom-allowed-value-test"
|
||||
annotationsValid := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `
|
||||
|
@ -155,14 +136,8 @@ var _ = framework.DescribeAnnotation("Bad annotation values", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("[BAD_ANNOTATIONS] should drop an ingress if there is a custom blocklist config in place and allow others to pass", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
host := "custom-forbidden-value-test"
|
||||
|
||||
annotations := map[string]string{
|
||||
|
|
|
@ -69,15 +69,9 @@ var _ = framework.DescribeSetting("Geoip2", func() {
|
|||
ginkgo.It("should only allow requests from specific countries", func() {
|
||||
ginkgo.Skip("GeoIP test are temporarily disabled")
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"use-geoip2": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
f.UpdateNginxConfigMapData("use-geoip2", "true")
|
||||
|
||||
httpSnippetAllowingOnlyAustralia := `map $geoip2_city_country_code $blocked_country {
|
||||
default 1;
|
||||
|
|
|
@ -34,14 +34,9 @@ var _ = framework.IngressNginxDescribe("Dynamic $proxy_host", func() {
|
|||
})
|
||||
|
||||
ginkgo.It("should exist a proxy_host", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
})
|
||||
}()
|
||||
disableSnippet := f.AllowSnippetConfiguration()
|
||||
defer disableSnippet()
|
||||
|
||||
upstreamName := fmt.Sprintf("%v-%v-80", f.Namespace, framework.EchoService)
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `more_set_headers "Custom-Header: $proxy_host"`,
|
||||
|
@ -65,10 +60,12 @@ var _ = framework.IngressNginxDescribe("Dynamic $proxy_host", func() {
|
|||
ginkgo.It("should exist a proxy_host using the upstream-vhost annotation value", func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"annotations-risk-level": "Critical", // To allow Configuration Snippet
|
||||
})
|
||||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
"annotations-risk-level": "High",
|
||||
})
|
||||
}()
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() {
|
|||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "true",
|
||||
"annotations-risk-level": "Critical",
|
||||
"server-snippet": `
|
||||
more_set_headers "Globalfoo: Foooo";`,
|
||||
})
|
||||
|
@ -45,6 +46,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() {
|
|||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
"annotations-risk-level": "High",
|
||||
})
|
||||
}()
|
||||
annotations := map[string]string{
|
||||
|
@ -101,6 +103,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() {
|
|||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
"annotations-risk-level": "Critical", // To allow Configuration Snippet
|
||||
"server-snippet": `
|
||||
more_set_headers "Globalfoo: Foooo";`,
|
||||
})
|
||||
|
@ -108,6 +111,7 @@ var _ = framework.DescribeSetting("configmap server-snippet", func() {
|
|||
defer func() {
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"allow-snippet-annotations": "false",
|
||||
"annotations-risk-level": "High",
|
||||
})
|
||||
}()
|
||||
annotations := map[string]string{
|
||||
|
|
|
@ -48,8 +48,8 @@ var _ = framework.IngressNginxDescribeSerial("annotation validations", func() {
|
|||
framework.Sleep()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/default-backend": "default/bla", // low risk
|
||||
"nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk
|
||||
"nginx.ingress.kubernetes.io/default-backend": "bla", // low risk
|
||||
"nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk
|
||||
}
|
||||
|
||||
ginkgo.By("allow ingress with low/medium risk annotations")
|
||||
|
@ -82,8 +82,8 @@ var _ = framework.IngressNginxDescribeSerial("annotation validations", func() {
|
|||
framework.Sleep()
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/default-backend": "default/bla", // low risk
|
||||
"nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk
|
||||
"nginx.ingress.kubernetes.io/default-backend": "bla", // low risk
|
||||
"nginx.ingress.kubernetes.io/denylist-source-range": "1.1.1.1/32", // medium risk
|
||||
}
|
||||
|
||||
ginkgo.By("allow ingress with low/medium risk annotations")
|
||||
|
|
|
@ -24,7 +24,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|||
export NAMESPACE=$1
|
||||
export NAMESPACE_OVERLAY=$2
|
||||
export IS_CHROOT=$3
|
||||
export ENABLE_VALIDATIONS=$4
|
||||
|
||||
echo "deploying NGINX Ingress controller in namespace $NAMESPACE"
|
||||
|
||||
|
@ -59,7 +58,7 @@ else
|
|||
# TODO: remove the need to use fullnameOverride
|
||||
fullnameOverride: nginx-ingress
|
||||
controller:
|
||||
enableAnnotationValidations: ${ENABLE_VALIDATIONS}
|
||||
enableAnnotationValidations: true
|
||||
image:
|
||||
repository: ingress-controller/controller
|
||||
chroot: ${IS_CHROOT}
|
||||
|
|
Loading…
Reference in a new issue