UPT: align waf options
This commit is contained in:
parent
04a89ce234
commit
bab521e81a
5 changed files with 48 additions and 59 deletions
|
@ -80,9 +80,9 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-debug](#lua-resty-waf)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-debug](#lua-resty-waf)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets](#lua-resty-waf)|string|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-ignore-rulesets](#lua-resty-waf)|string|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-extra-rules](#lua-resty-waf)|string|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-extra-rules](#lua-resty-waf)|string|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content](#lua-resty-waf)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content-types](#lua-resty-waf)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-score](#lua-resty-waf)|number|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-score-threshold](#lua-resty-waf)|number|
|
||||||
|[nginx.ingress.kubernetes.io/lua-resty-waf-disable-multipart-body](#lua-resty-waf)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/lua-resty-waf-process-multipart-body](#lua-resty-waf)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/enable-influxdb](#influxdb)|"true" or "false"|
|
|[nginx.ingress.kubernetes.io/enable-influxdb](#influxdb)|"true" or "false"|
|
||||||
|[nginx.ingress.kubernetes.io/influxdb-measurement](#influxdb)|string|
|
|[nginx.ingress.kubernetes.io/influxdb-measurement](#influxdb)|string|
|
||||||
|[nginx.ingress.kubernetes.io/influxdb-port](#influxdb)|string|
|
|[nginx.ingress.kubernetes.io/influxdb-port](#influxdb)|string|
|
||||||
|
@ -566,14 +566,14 @@ We can enable the following annotation for allow all contents type:
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content: "true"
|
nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content-types: "true"
|
||||||
```
|
```
|
||||||
|
|
||||||
The default score of lua-resty-waf is 5, which usually triggered if hitting 2 default rules, you can modify the score threshold with following annotation:
|
The default score of lua-resty-waf is 5, which usually triggered if hitting 2 default rules, you can modify the score threshold with following annotation:
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
nginx.ingress.kubernetes.io/lua-resty-waf-score: "10"
|
nginx.ingress.kubernetes.io/lua-resty-waf-score-threshold: "10"
|
||||||
```
|
```
|
||||||
|
|
||||||
When you enabled HTTPS in the endpoint and since resty-lua will return 500 error when processing "multipart" contents
|
When you enabled HTTPS in the endpoint and since resty-lua will return 500 error when processing "multipart" contents
|
||||||
|
@ -581,21 +581,7 @@ Reference for this [issue](https://github.com/p0pr0ck5/lua-resty-waf/issues/166)
|
||||||
You may enable the following annotation for work around:
|
You may enable the following annotation for work around:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
nginx.ingress.kubernetes.io/lua-resty-waf-disable-multipart-body: "true"
|
nginx.ingress.kubernetes.io/lua-resty-waf-process-multipart-body: "false"
|
||||||
```
|
|
||||||
|
|
||||||
For details on how to write WAF rules, please refer to [https://github.com/p0pr0ck5/lua-resty-waf](https://github.com/p0pr0ck5/lua-resty-waf).
|
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content: "true"
|
|
||||||
```
|
|
||||||
|
|
||||||
The default score of lua-resty-waf is 5, which usually triggered if hitting 2 default rules, you can modify the score threshold with following annotation:
|
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
nginx.ingress.kubernetes.io/lua-resty-waf-score: "10"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
For details on how to write WAF rules, please refer to [https://github.com/p0pr0ck5/lua-resty-waf](https://github.com/p0pr0ck5/lua-resty-waf).
|
For details on how to write WAF rules, please refer to [https://github.com/p0pr0ck5/lua-resty-waf](https://github.com/p0pr0ck5/lua-resty-waf).
|
||||||
|
|
|
@ -31,13 +31,13 @@ var luaRestyWAFModes = map[string]bool{"ACTIVE": true, "INACTIVE": true, "SIMULA
|
||||||
|
|
||||||
// Config returns lua-resty-waf configuration for an Ingress rule
|
// Config returns lua-resty-waf configuration for an Ingress rule
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
Debug bool `json:"debug"`
|
Debug bool `json:"debug"`
|
||||||
IgnoredRuleSets []string `json:"ignored-rulesets"`
|
IgnoredRuleSets []string `json:"ignored-rulesets"`
|
||||||
ExtraRulesetString string `json:"extra-ruleset-string"`
|
ExtraRulesetString string `json:"extra-ruleset-string"`
|
||||||
Score int `json:"score"`
|
ScoreThreshold int `json:"score-threshold"`
|
||||||
AllowUnknownContent bool `json:"allow-unknown-content"`
|
AllowUnknownContentTypes bool `json:"allow-unknown-content-types"`
|
||||||
DisableMultipartBody bool `json:"disable-multipart-body"`
|
ProcessMultipartBody bool `json:"process-multipart-body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal tests for equality between two Config types
|
// Equal tests for equality between two Config types
|
||||||
|
@ -60,13 +60,13 @@ func (e1 *Config) Equal(e2 *Config) bool {
|
||||||
if e1.ExtraRulesetString != e2.ExtraRulesetString {
|
if e1.ExtraRulesetString != e2.ExtraRulesetString {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if e1.Score != e2.Score {
|
if e1.ScoreThreshold != e2.ScoreThreshold {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if e1.AllowUnknownContent != e2.AllowUnknownContent {
|
if e1.AllowUnknownContentTypes != e2.AllowUnknownContentTypes {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if e1.DisableMultipartBody != e2.DisableMultipartBody {
|
if e1.ProcessMultipartBody != e2.ProcessMultipartBody {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,19 +107,19 @@ func (a luarestywaf) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||||
// TODO(elvinefendi) maybe validate the ruleset string here
|
// TODO(elvinefendi) maybe validate the ruleset string here
|
||||||
extraRulesetString, _ := parser.GetStringAnnotation("lua-resty-waf-extra-rules", ing)
|
extraRulesetString, _ := parser.GetStringAnnotation("lua-resty-waf-extra-rules", ing)
|
||||||
|
|
||||||
score, _ := parser.GetIntAnnotation("lua-resty-waf-score", ing)
|
scoreThreshold, _ := parser.GetIntAnnotation("lua-resty-waf-score-threshold", ing)
|
||||||
|
|
||||||
allowUnknownContent, _ := parser.GetBoolAnnotation("lua-resty-waf-allow-unknown-content", ing)
|
allowUnknownContentTypes, _ := parser.GetBoolAnnotation("lua-resty-waf-allow-unknown-content-types", ing)
|
||||||
|
|
||||||
disableMultipartBody, _ := parser.GetBoolAnnotation("lua-resty-waf-disable-multipart-body", ing)
|
processMultipartBody, _ := parser.GetBoolAnnotation("lua-resty-waf-process-multipart-body", ing)
|
||||||
|
|
||||||
return &Config{
|
return &Config{
|
||||||
Mode: mode,
|
Mode: mode,
|
||||||
Debug: debug,
|
Debug: debug,
|
||||||
IgnoredRuleSets: ignoredRuleSets,
|
IgnoredRuleSets: ignoredRuleSets,
|
||||||
ExtraRulesetString: extraRulesetString,
|
ExtraRulesetString: extraRulesetString,
|
||||||
Score: score,
|
ScoreThreshold: scoreThreshold,
|
||||||
AllowUnknownContent: allowUnknownContent,
|
AllowUnknownContentTypes: allowUnknownContentTypes,
|
||||||
DisableMultipartBody: disableMultipartBody,
|
ProcessMultipartBody: processMultipartBody,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@ func TestParse(t *testing.T) {
|
||||||
luaRestyWAFAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf")
|
luaRestyWAFAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf")
|
||||||
luaRestyWAFDebugAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-debug")
|
luaRestyWAFDebugAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-debug")
|
||||||
luaRestyWAFIgnoredRuleSetsAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-ignore-rulesets")
|
luaRestyWAFIgnoredRuleSetsAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-ignore-rulesets")
|
||||||
luaRestyWAFScoreAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-score")
|
luaRestyWAFScoreThresholdAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-score-threshold")
|
||||||
luaRestyWAFAllowUnknownAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-allow-unknown-content")
|
luaRestyWAFAllowUnknownContentTypesAnnotation := parser.GetAnnotationWithPrefix("lua-resty-waf-allow-unknown-content-types")
|
||||||
luaRestyWAFDisableMultipartBody := parser.GetAnnotationWithPrefix("lua-resty-waf-disable-multipart-body")
|
luaRestyWAFProcessMultipartBody := parser.GetAnnotationWithPrefix("lua-resty-waf-process-multipart-body")
|
||||||
|
|
||||||
ap := NewParser(&resolver.Mock{})
|
ap := NewParser(&resolver.Mock{})
|
||||||
if ap == nil {
|
if ap == nil {
|
||||||
|
@ -54,17 +54,17 @@ func TestParse(t *testing.T) {
|
||||||
{map[string]string{luaRestyWAFAnnotation: "inactive", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "INACTIVE", Debug: true, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "inactive", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "INACTIVE", Debug: true, IgnoredRuleSets: []string{}}},
|
||||||
|
|
||||||
{map[string]string{
|
{map[string]string{
|
||||||
luaRestyWAFAnnotation: "active",
|
luaRestyWAFAnnotation: "active",
|
||||||
luaRestyWAFDebugAnnotation: "true",
|
luaRestyWAFDebugAnnotation: "true",
|
||||||
luaRestyWAFIgnoredRuleSetsAnnotation: "ruleset1, ruleset2 ruleset3, another.ruleset",
|
luaRestyWAFIgnoredRuleSetsAnnotation: "ruleset1, ruleset2 ruleset3, another.ruleset",
|
||||||
luaRestyWAFScoreAnnotation: "10",
|
luaRestyWAFScoreThresholdAnnotation: "10",
|
||||||
luaRestyWAFAllowUnknownAnnotation: "true"},
|
luaRestyWAFAllowUnknownContentTypesAnnotation: "true"},
|
||||||
&Config{Mode: "ACTIVE", Debug: true, IgnoredRuleSets: []string{"ruleset1", "ruleset2", "ruleset3", "another.ruleset"}, Score: 10, AllowUnknownContent: true}},
|
&Config{Mode: "ACTIVE", Debug: true, IgnoredRuleSets: []string{"ruleset1", "ruleset2", "ruleset3", "another.ruleset"}, ScoreThreshold: 10, AllowUnknownContentTypes: true}},
|
||||||
|
|
||||||
{map[string]string{luaRestyWAFAnnotation: "siMulate", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "SIMULATE", Debug: true, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "siMulate", luaRestyWAFDebugAnnotation: "true"}, &Config{Mode: "SIMULATE", Debug: true, IgnoredRuleSets: []string{}}},
|
||||||
{map[string]string{luaRestyWAFAnnotation: "siMulateX", luaRestyWAFDebugAnnotation: "true"}, &Config{Debug: false}},
|
{map[string]string{luaRestyWAFAnnotation: "siMulateX", luaRestyWAFDebugAnnotation: "true"}, &Config{Debug: false}},
|
||||||
|
|
||||||
{map[string]string{luaRestyWAFAnnotation: "active", luaRestyWAFDisableMultipartBody: "false"}, &Config{Mode: "ACTIVE", DisableMultipartBody: false, IgnoredRuleSets: []string{}}},
|
{map[string]string{luaRestyWAFAnnotation: "active", luaRestyWAFProcessMultipartBody: "false"}, &Config{Mode: "ACTIVE", ProcessMultipartBody: false, IgnoredRuleSets: []string{}}},
|
||||||
}
|
}
|
||||||
|
|
||||||
ing := &extensions.Ingress{
|
ing := &extensions.Ingress{
|
||||||
|
|
|
@ -892,7 +892,7 @@ stream {
|
||||||
waf:set_option("mode", "{{ $location.LuaRestyWAF.Mode }}")
|
waf:set_option("mode", "{{ $location.LuaRestyWAF.Mode }}")
|
||||||
waf:set_option("storage_zone", "waf_storage")
|
waf:set_option("storage_zone", "waf_storage")
|
||||||
|
|
||||||
{{ if $location.LuaRestyWAF.AllowUnknownContent }}
|
{{ if $location.LuaRestyWAF.AllowUnknownContentTypes }}
|
||||||
waf:set_option("allow_unknown_content_types", true)
|
waf:set_option("allow_unknown_content_types", true)
|
||||||
{{ else }}
|
{{ else }}
|
||||||
waf:set_option("allowed_content_types", { "text/html", "text/json", "application/json" })
|
waf:set_option("allowed_content_types", { "text/html", "text/json", "application/json" })
|
||||||
|
@ -900,12 +900,14 @@ stream {
|
||||||
|
|
||||||
waf:set_option("event_log_level", ngx.WARN)
|
waf:set_option("event_log_level", ngx.WARN)
|
||||||
|
|
||||||
{{ if gt $location.LuaRestyWAF.Score 0 }}
|
{{ if gt $location.LuaRestyWAF.ScoreThreshold 0 }}
|
||||||
waf:set_option("score_threshold", {{ $location.LuaRestyWAF.Score }})
|
waf:set_option("score_threshold", {{ $location.LuaRestyWAF.ScoreThreshold }})
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ if $location.LuaRestyWAF.DisableMultipartBody }}
|
{{ if not $location.LuaRestyWAF.ProcessMultipartBody }}
|
||||||
waf:set_option("process_multipart_body", false)
|
waf:set_option("process_multipart_body", false)
|
||||||
|
{{ else }}
|
||||||
|
waf:set_option("process_multipart_body", true)
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ if $location.LuaRestyWAF.Debug }}
|
{{ if $location.LuaRestyWAF.Debug }}
|
||||||
|
|
|
@ -68,8 +68,8 @@ var _ = framework.IngressNginxDescribe("Annotations - lua-resty-waf", func() {
|
||||||
It("should apply the score threshold", func() {
|
It("should apply the score threshold", func() {
|
||||||
host := "foo"
|
host := "foo"
|
||||||
createIngress(f, host, "http-svc", 80, map[string]string{
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/lua-resty-waf": "active",
|
"nginx.ingress.kubernetes.io/lua-resty-waf": "active",
|
||||||
"nginx.ingress.kubernetes.io/lua-resty-waf-score": "20"})
|
"nginx.ingress.kubernetes.io/lua-resty-waf-score-threshold": "20"})
|
||||||
|
|
||||||
url := fmt.Sprintf("%s?msg=<A href=\"http://mysite.com/\">XSS</A>", f.IngressController.HTTPURL)
|
url := fmt.Sprintf("%s?msg=<A href=\"http://mysite.com/\">XSS</A>", f.IngressController.HTTPURL)
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
|
@ -84,7 +84,8 @@ var _ = framework.IngressNginxDescribe("Annotations - lua-resty-waf", func() {
|
||||||
host := "foo"
|
host := "foo"
|
||||||
contenttype := "application/octet-stream"
|
contenttype := "application/octet-stream"
|
||||||
createIngress(f, host, "http-svc", 80, map[string]string{
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/lua-resty-waf": "active"})
|
"nginx.ingress.kubernetes.io/lua-resty-waf-allow-unknown-content-types": "true",
|
||||||
|
"nginx.ingress.kubernetes.io/lua-resty-waf": "active"})
|
||||||
|
|
||||||
url := fmt.Sprintf("%s?msg=my-message", f.IngressController.HTTPURL)
|
url := fmt.Sprintf("%s?msg=my-message", f.IngressController.HTTPURL)
|
||||||
resp, _, errs := gorequest.New().
|
resp, _, errs := gorequest.New().
|
||||||
|
@ -94,13 +95,13 @@ var _ = framework.IngressNginxDescribe("Annotations - lua-resty-waf", func() {
|
||||||
End()
|
End()
|
||||||
|
|
||||||
Expect(len(errs)).Should(Equal(0))
|
Expect(len(errs)).Should(Equal(0))
|
||||||
Expect(resp.StatusCode).Should(Equal(http.StatusForbidden))
|
Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
})
|
})
|
||||||
It("should allow the multipart content type", func() {
|
It("should allow the multipart content type", func() {
|
||||||
host := "foo"
|
host := "foo"
|
||||||
contenttype := "multipart/form-data; boundary=alamofire.boundary.3fc2e849279e18fc"
|
contenttype := "multipart/form-data; boundary=alamofire.boundary.3fc2e849279e18fc"
|
||||||
createIngress(f, host, "http-svc", 80, map[string]string{
|
createIngress(f, host, "http-svc", 80, map[string]string{
|
||||||
"nginx.ingress.kubernetes.io/lua-resty-waf-disable-multipart-body": "true",
|
"nginx.ingress.kubernetes.io/lua-resty-waf-process-multipart-body": "false",
|
||||||
"nginx.ingress.kubernetes.io/lua-resty-waf": "active"})
|
"nginx.ingress.kubernetes.io/lua-resty-waf": "active"})
|
||||||
|
|
||||||
url := fmt.Sprintf("%s?msg=my-message", f.IngressController.HTTPURL)
|
url := fmt.Sprintf("%s?msg=my-message", f.IngressController.HTTPURL)
|
||||||
|
|
Loading…
Reference in a new issue