* Add option to force enabling snippet directives (#7665) Signed-off-by: Ricardo Pchevuzinske Katz <ricardo.katz@gmail.com> * Add missing key when cherry-picking
This commit is contained in:
parent
f44bbe9b03
commit
64e2bed508
12 changed files with 459 additions and 24 deletions
|
|
@ -282,7 +282,7 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return true
|
||||
return strings.Contains(server, "SecRequestBodyAccess On")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
|
|
@ -292,4 +292,44 @@ var _ = framework.DescribeAnnotation("modsecurity owasp", func() {
|
|||
Expect().
|
||||
Status(http.StatusForbidden)
|
||||
})
|
||||
|
||||
ginkgo.It("should enable modsecurity through the config map but ignore snippet as disabled by admin", func() {
|
||||
host := "modsecurity.foo.com"
|
||||
nameSpace := f.Namespace
|
||||
|
||||
snippet := `SecRequestBodyAccess On
|
||||
SecAuditEngine RelevantOnly
|
||||
SecAuditLogParts ABIJDEFHZ
|
||||
SecAuditLog /dev/stdout
|
||||
SecAuditLogType Serial
|
||||
SecRule REQUEST_HEADERS:User-Agent \"block-ua\" \"log,deny,id:107,status:403,msg:\'UA blocked\'\"`
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/modsecurity-snippet": snippet,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, nameSpace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
expectedComment := "SecRuleEngine On"
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"enable-modsecurity": "true",
|
||||
"enable-owasp-modsecurity-crs": "true",
|
||||
"enable-snippet-directives": "false",
|
||||
"modsecurity-snippet": expectedComment,
|
||||
})
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return !strings.Contains(server, "block-ua")
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
WithHeader("User-Agent", "block-ua").
|
||||
Expect().
|
||||
Status(http.StatusOK)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package annotations
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
|
|
@ -35,8 +36,8 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
host := "serversnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/server-snippet": `
|
||||
more_set_headers "Content-Length: $content_length";
|
||||
more_set_headers "Content-Type: $content_type";`,
|
||||
more_set_headers "Foo: Bar";
|
||||
more_set_headers "Xpto: Lalala";`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
|
|
@ -44,8 +45,50 @@ var _ = framework.DescribeAnnotation("server-snippet", func() {
|
|||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `more_set_headers "Content-Length: $content_length`) &&
|
||||
strings.Contains(server, `more_set_headers "Content-Type: $content_type";`)
|
||||
return strings.Contains(server, `more_set_headers "Foo: Bar`) &&
|
||||
strings.Contains(server, `more_set_headers "Xpto: Lalala";`)
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Foo", []string{"Bar"}).
|
||||
ValueEqual("Xpto", []string{"Lalala"})
|
||||
})
|
||||
|
||||
ginkgo.It(`drops server snippet if disabled by the administrator`, func() {
|
||||
host := "noserversnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/server-snippet": `
|
||||
more_set_headers "Foo: Bar";
|
||||
more_set_headers "Xpto: Lalala";`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.UpdateNginxConfigMapData("enable-snippet-directives", "false")
|
||||
defer func() {
|
||||
// Return to the original value
|
||||
f.UpdateNginxConfigMapData("enable-snippet-directives", "true")
|
||||
}()
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return !strings.Contains(server, `more_set_headers "Foo: Bar`) &&
|
||||
!strings.Contains(server, `more_set_headers "Xpto: Lalala";`)
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
NotContainsKey("Foo").
|
||||
NotContainsKey("Xpto")
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package annotations
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
|
|
@ -31,11 +32,11 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
|
|||
f.NewEchoDeployment()
|
||||
})
|
||||
|
||||
ginkgo.It(`set snippet "more_set_headers "Request-Id: $req_id";" in all locations"`, func() {
|
||||
ginkgo.It(`set snippet "more_set_headers "Foo1: Bar1";" in all locations"`, func() {
|
||||
host := "configurationsnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `
|
||||
more_set_headers "Request-Id: $req_id";`,
|
||||
more_set_headers "Foo1: Bar1";`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
|
|
@ -43,7 +44,44 @@ var _ = framework.DescribeAnnotation("configuration-snippet", func() {
|
|||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `more_set_headers "Request-Id: $req_id";`)
|
||||
return strings.Contains(server, `more_set_headers "Foo1: Bar1";`)
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Foo1", []string{"Bar1"})
|
||||
})
|
||||
|
||||
ginkgo.It(`drops snippet "more_set_headers "Foo1: Bar1";" in all locations if disabled by admin"`, func() {
|
||||
host := "noconfigurationsnippet.foo.com"
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/configuration-snippet": `
|
||||
more_set_headers "Foo1: Bar1";`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.UpdateNginxConfigMapData("enable-snippet-directives", "false")
|
||||
defer func() {
|
||||
// Return to the original value
|
||||
f.UpdateNginxConfigMapData("enable-snippet-directives", "true")
|
||||
}()
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return !strings.Contains(server, `more_set_headers "Foo1: Bar1";`)
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
NotContainsKey("Foo1")
|
||||
})
|
||||
})
|
||||
|
|
|
|||
149
test/e2e/settings/server_snippet.go
Normal file
149
test/e2e/settings/server_snippet.go
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package settings
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
|
||||
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||
)
|
||||
|
||||
var _ = framework.DescribeSetting("configmap server-snippet", func() {
|
||||
f := framework.NewDefaultFramework("cm-server-snippet")
|
||||
|
||||
ginkgo.BeforeEach(func() {
|
||||
f.NewEchoDeployment()
|
||||
})
|
||||
|
||||
ginkgo.It("should add value of server-snippet setting to all ingress config", func() {
|
||||
host := "serverglobalsnippet1.foo.com"
|
||||
hostAnnots := "serverannotssnippet1.foo.com"
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"server-snippet": `
|
||||
more_set_headers "Globalfoo: Foooo";`,
|
||||
})
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/server-snippet": `
|
||||
more_set_headers "Foo: Bar";
|
||||
more_set_headers "Xpto: Lalala";`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
ing1 := framework.NewSingleIngress(hostAnnots, "/", hostAnnots, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing1)
|
||||
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `more_set_headers "Globalfoo: Foooo`) &&
|
||||
!strings.Contains(server, `more_set_headers "Foo: Bar";`) &&
|
||||
!strings.Contains(server, `more_set_headers "Xpto: Lalala";`)
|
||||
})
|
||||
|
||||
f.WaitForNginxServer(hostAnnots,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `more_set_headers "Globalfoo: Foooo`) &&
|
||||
strings.Contains(server, `more_set_headers "Foo: Bar";`) &&
|
||||
strings.Contains(server, `more_set_headers "Xpto: Lalala";`)
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Globalfoo", []string{"Foooo"}).
|
||||
NotContainsKey("Foo").
|
||||
NotContainsKey("Xpto")
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", hostAnnots).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Foo", []string{"Bar"}).
|
||||
ValueEqual("Xpto", []string{"Lalala"}).
|
||||
ValueEqual("Globalfoo", []string{"Foooo"})
|
||||
})
|
||||
|
||||
ginkgo.It("should add global server-snippet and drop annotations per admin config", func() {
|
||||
host := "serverglobalsnippet2.foo.com"
|
||||
hostAnnots := "serverannotssnippet2.foo.com"
|
||||
|
||||
f.SetNginxConfigMapData(map[string]string{
|
||||
"enable-snippet-directives": "false",
|
||||
"server-snippet": `
|
||||
more_set_headers "Globalfoo: Foooo";`,
|
||||
})
|
||||
|
||||
annotations := map[string]string{
|
||||
"nginx.ingress.kubernetes.io/server-snippet": `
|
||||
more_set_headers "Foo: Bar";
|
||||
more_set_headers "Xpto: Lalala";`,
|
||||
}
|
||||
|
||||
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, nil)
|
||||
f.EnsureIngress(ing)
|
||||
|
||||
ing1 := framework.NewSingleIngress(hostAnnots, "/", hostAnnots, f.Namespace, framework.EchoService, 80, annotations)
|
||||
f.EnsureIngress(ing1)
|
||||
|
||||
// Sleep a while just to guarantee that the configmap is applied
|
||||
framework.Sleep()
|
||||
|
||||
f.WaitForNginxServer(host,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `more_set_headers "Globalfoo: Foooo`) &&
|
||||
!strings.Contains(server, `more_set_headers "Foo: Bar";`) &&
|
||||
!strings.Contains(server, `more_set_headers "Xpto: Lalala";`)
|
||||
})
|
||||
|
||||
f.WaitForNginxServer(hostAnnots,
|
||||
func(server string) bool {
|
||||
return strings.Contains(server, `more_set_headers "Globalfoo: Foooo`) &&
|
||||
!strings.Contains(server, `more_set_headers "Foo: Bar";`) &&
|
||||
!strings.Contains(server, `more_set_headers "Xpto: Lalala";`)
|
||||
})
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", host).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Globalfoo", []string{"Foooo"}).
|
||||
NotContainsKey("Foo").
|
||||
NotContainsKey("Xpto")
|
||||
|
||||
f.HTTPTestClient().
|
||||
GET("/").
|
||||
WithHeader("Host", hostAnnots).
|
||||
Expect().
|
||||
Status(http.StatusOK).Headers().
|
||||
ValueEqual("Globalfoo", []string{"Foooo"}).
|
||||
NotContainsKey("Foo").
|
||||
NotContainsKey("Xpto")
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue