mirror of
https://github.com/alibaba/higress.git
synced 2026-06-07 11:47:30 +08:00
feat: add request block regular matching and modify block_ Urls are e… (#517)
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 |
|
||||||
| -------- | -------- | -------- | -------- | -------- |
|
| -------- | -------- | -------- | -------- | -------- |
|
||||||
| block_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的字符串 |
|
| block_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的字符串 |
|
||||||
|
| block_exact_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要精确屏蔽 URL 的字符串 |
|
||||||
|
| block_regexp_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的正则表达式 |
|
||||||
| block_headers | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Header 的字符串 |
|
| block_headers | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Header 的字符串 |
|
||||||
| block_bodies | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Body 的字符串 |
|
| block_bodies | array of string | 选填,`block_urls`,`block_headers`,`block_bodies` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Body 的字符串 |
|
||||||
| blocked_code | number | 选填 | 403 | 配置请求被屏蔽时返回的 HTTP 状态码 |
|
| blocked_code | number | 选填 | 403 | 配置请求被屏蔽时返回的 HTTP 状态码 |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.0.0
|
1.0.1
|
||||||
@@ -17,6 +17,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
|
||||||
@@ -36,12 +37,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RequestBlockConfig struct {
|
type RequestBlockConfig struct {
|
||||||
blockedCode uint32
|
blockedCode uint32
|
||||||
blockedMessage string
|
blockedMessage string
|
||||||
caseSensitive bool
|
caseSensitive bool
|
||||||
blockUrls []string
|
blockUrls []string
|
||||||
blockHeaders []string
|
blockExactUrls []string
|
||||||
blockBodies []string
|
blockHeaders []string
|
||||||
|
blockBodies []string
|
||||||
|
blockRegExpArray []*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseConfig(json gjson.Result, config *RequestBlockConfig, log wrapper.Log) error {
|
func parseConfig(json gjson.Result, config *RequestBlockConfig, log wrapper.Log) error {
|
||||||
@@ -64,6 +67,30 @@ func parseConfig(json gjson.Result, config *RequestBlockConfig, log wrapper.Log)
|
|||||||
config.blockUrls = append(config.blockUrls, strings.ToLower(url))
|
config.blockUrls = append(config.blockUrls, strings.ToLower(url))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, item := range json.Get("block_exact_urls").Array() {
|
||||||
|
url := item.String()
|
||||||
|
if url == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if config.caseSensitive {
|
||||||
|
config.blockExactUrls = append(config.blockExactUrls, url)
|
||||||
|
} else {
|
||||||
|
config.blockExactUrls = append(config.blockExactUrls, strings.ToLower(url))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, item := range json.Get("block_regexp_urls").Array() {
|
||||||
|
regexpUrl := item.String()
|
||||||
|
if regexpUrl == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if config.caseSensitive {
|
||||||
|
reg := regexp.MustCompile(regexpUrl)
|
||||||
|
config.blockRegExpArray = append(config.blockRegExpArray, reg)
|
||||||
|
} else {
|
||||||
|
reg := regexp.MustCompile(strings.ToLower(regexpUrl))
|
||||||
|
config.blockRegExpArray = append(config.blockRegExpArray, reg)
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, item := range json.Get("block_headers").Array() {
|
for _, item := range json.Get("block_headers").Array() {
|
||||||
header := item.String()
|
header := item.String()
|
||||||
if header == "" {
|
if header == "" {
|
||||||
@@ -103,12 +130,24 @@ func onHttpRequestHeaders(ctx wrapper.HttpContext, config RequestBlockConfig, lo
|
|||||||
if !config.caseSensitive {
|
if !config.caseSensitive {
|
||||||
requestUrl = strings.ToLower(requestUrl)
|
requestUrl = strings.ToLower(requestUrl)
|
||||||
}
|
}
|
||||||
|
for _, blockExactUrl := range config.blockExactUrls {
|
||||||
|
if requestUrl == blockExactUrl {
|
||||||
|
proxywasm.SendHttpResponse(config.blockedCode, nil, []byte(config.blockedMessage), -1)
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, blockUrl := range config.blockUrls {
|
for _, blockUrl := range config.blockUrls {
|
||||||
if strings.Contains(requestUrl, blockUrl) {
|
if strings.Contains(requestUrl, blockUrl) {
|
||||||
proxywasm.SendHttpResponse(config.blockedCode, nil, []byte(config.blockedMessage), -1)
|
proxywasm.SendHttpResponse(config.blockedCode, nil, []byte(config.blockedMessage), -1)
|
||||||
return types.ActionContinue
|
return types.ActionContinue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, regExpObj := range config.blockRegExpArray {
|
||||||
|
if regExpObj.MatchString(requestUrl) {
|
||||||
|
proxywasm.SendHttpResponse(config.blockedCode, nil, []byte(config.blockedMessage), -1)
|
||||||
|
return types.ActionContinue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(config.blockHeaders) > 0 {
|
if len(config.blockHeaders) > 0 {
|
||||||
headers, err := proxywasm.GetHttpRequestHeaders()
|
headers, err := proxywasm.GetHttpRequestHeaders()
|
||||||
|
|||||||
@@ -50,6 +50,42 @@ var WasmPluginsRequestBlock = suite.ConformanceTest{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TargetBackend: "infra-backend-v1",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/env/info",
|
||||||
|
UnfollowRedirect: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 403,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Meta: http.AssertionMeta{
|
||||||
|
TargetBackend: "infra-backend-v1",
|
||||||
|
TargetNamespace: "higress-conformance-infra",
|
||||||
|
},
|
||||||
|
Request: http.AssertionRequest{
|
||||||
|
ActualRequest: http.Request{
|
||||||
|
Host: "foo.com",
|
||||||
|
Path: "/web/info",
|
||||||
|
UnfollowRedirect: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Response: http.AssertionResponse{
|
||||||
|
ExpectedResponse: http.Response{
|
||||||
|
StatusCode: 403,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
t.Run("WasmPlugins request-block", func(t *testing.T) {
|
t.Run("WasmPlugins request-block", func(t *testing.T) {
|
||||||
for _, testcase := range testcases {
|
for _, testcase := range testcases {
|
||||||
|
|||||||
@@ -42,4 +42,8 @@ spec:
|
|||||||
defaultConfig:
|
defaultConfig:
|
||||||
block_urls:
|
block_urls:
|
||||||
- "swagger.html"
|
- "swagger.html"
|
||||||
|
block_regexp_urls:
|
||||||
|
- "/env.*"
|
||||||
|
block_exact_urls:
|
||||||
|
- "/web/info"
|
||||||
url: file:///opt/plugins/wasm-go/extensions/request-block/plugin.wasm
|
url: file:///opt/plugins/wasm-go/extensions/request-block/plugin.wasm
|
||||||
|
|||||||
Reference in New Issue
Block a user