From 268c73301e78514552fe0576fb0059c42c854a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BE=84=E6=BD=AD?= Date: Thu, 10 Nov 2022 17:02:43 +0800 Subject: [PATCH] change route name (#51) --- pkg/ingress/kube/common/controller.go | 2 +- pkg/ingress/kube/common/tool.go | 24 +----- pkg/ingress/kube/common/tool_test.go | 62 +------------ .../extensions/request-block/README.md | 86 +++++++++++++++++++ .../wasm-go/extensions/request-block/VERSION | 1 + 5 files changed, 93 insertions(+), 82 deletions(-) create mode 100644 plugins/wasm-go/extensions/request-block/README.md create mode 100644 plugins/wasm-go/extensions/request-block/VERSION diff --git a/pkg/ingress/kube/common/controller.go b/pkg/ingress/kube/common/controller.go index 779635d0a..a4421f772 100644 --- a/pkg/ingress/kube/common/controller.go +++ b/pkg/ingress/kube/common/controller.go @@ -73,7 +73,7 @@ type WrapperHTTPRoute struct { } func (w *WrapperHTTPRoute) Meta() string { - return strings.Join([]string{w.WrapperConfig.Config.Namespace, w.WrapperConfig.Config.Name}, "-") + return strings.Join([]string{w.WrapperConfig.Config.Namespace, w.WrapperConfig.Config.Name}, "/") } func (w *WrapperHTTPRoute) BasePathFormat() string { diff --git a/pkg/ingress/kube/common/tool.go b/pkg/ingress/kube/common/tool.go index f01a9bd17..b96e9b6ff 100644 --- a/pkg/ingress/kube/common/tool.go +++ b/pkg/ingress/kube/common/tool.go @@ -267,31 +267,11 @@ func partMd5(raw string) string { } func GenerateUniqueRouteName(route *WrapperHTTPRoute) string { - raw := constructRouteName(route) - - // meta-part-clusterId - // meta: ingressNamespace-ingressName - meta := route.Meta() - // host-pathType-path-header-queryParam, md5, then before 4 char and end 4 char - part := partMd5(raw) - routeName := CreateConvertedName(meta, part, route.ClusterId) - - if route.WrapperConfig.AnnotationsConfig.IsCanary() { - return routeName + "-canary" - } - - return routeName + return route.Meta() } func GenerateUniqueRouteNameWithSuffix(route *WrapperHTTPRoute, suffix string) string { - raw := constructRouteName(route) - - // meta-part-clusterId - // meta: ingressNamespace-ingressName - meta := route.Meta() - // host-pathType-path-header-queryParam, md5, then before 4 char and end 4 char - part := partMd5(raw) - return CreateConvertedName(meta, part, route.ClusterId, suffix) + return CreateConvertedName(route.Meta(), suffix) } func SplitServiceFQDN(fqdn string) (string, string, bool) { diff --git a/pkg/ingress/kube/common/tool_test.go b/pkg/ingress/kube/common/tool_test.go index 39f99eeac..b3451f451 100644 --- a/pkg/ingress/kube/common/tool_test.go +++ b/pkg/ingress/kube/common/tool_test.go @@ -23,6 +23,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/alibaba/higress/pkg/ingress/kube/annotations" + "github.com/stretchr/testify/assert" ) func TestConstructRouteName(t *testing.T) { @@ -151,7 +152,7 @@ func TestConstructRouteName(t *testing.T) { } func TestGenerateUniqueRouteName(t *testing.T) { - inputWithoutCanary := &WrapperHTTPRoute{ + input := &WrapperHTTPRoute{ WrapperConfig: &WrapperConfig{ Config: &config.Config{ Meta: config.Meta{ @@ -197,65 +198,8 @@ func TestGenerateUniqueRouteName(t *testing.T) { }, } - withoutCanary := GenerateUniqueRouteName(inputWithoutCanary) - t.Log(withoutCanary) + assert.Equal(t, "bar/foo", GenerateUniqueRouteName(input)) - inputWithCanary := &WrapperHTTPRoute{ - WrapperConfig: &WrapperConfig{ - Config: &config.Config{ - Meta: config.Meta{ - Name: "foo", - Namespace: "bar", - }, - }, - AnnotationsConfig: &annotations.Ingress{ - Canary: &annotations.CanaryConfig{ - Enabled: true, - }, - }, - }, - Host: "test.com", - OriginPathType: Prefix, - OriginPath: "/test", - ClusterId: "cluster1", - HTTPRoute: &networking.HTTPRoute{ - Match: []*networking.HTTPMatchRequest{ - { - Headers: map[string]*networking.StringMatch{ - "f": { - MatchType: &networking.StringMatch_Regex{ - Regex: "abc?", - }, - }, - "e": { - MatchType: &networking.StringMatch_Exact{ - Exact: "bye", - }, - }, - }, - QueryParams: map[string]*networking.StringMatch{ - "b": { - MatchType: &networking.StringMatch_Regex{ - Regex: "a?c.*", - }, - }, - "a": { - MatchType: &networking.StringMatch_Exact{ - Exact: "hello", - }, - }, - }, - }, - }, - }, - } - - withCanary := GenerateUniqueRouteName(inputWithCanary) - t.Log(withCanary) - - if withCanary != withoutCanary+"-canary" { - t.Fatalf("Expect %s, but actual is %s", withCanary, withoutCanary+"-canary") - } } func TestGetLbStatusList(t *testing.T) { diff --git a/plugins/wasm-go/extensions/request-block/README.md b/plugins/wasm-go/extensions/request-block/README.md new file mode 100644 index 000000000..d334aacd0 --- /dev/null +++ b/plugins/wasm-go/extensions/request-block/README.md @@ -0,0 +1,86 @@ +# 功能说明 +`request-block`插件实现了基于 URL、请求头等特征屏蔽 HTTP 请求,可以用于防护部分站点资源不对外部暴露 + +# 配置字段 + +| 名称 | 数据类型 | 填写要求 | 默认值 | 描述 | +| -------- | -------- | -------- | -------- | -------- | +| block_urls | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽 URL 的字符串 | +| block_headers | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Header 的字符串 | +| block_bodys | array of string | 选填,`block_urls`,`block_headers`,`block_bodys` 中至少必填一项 | - | 配置用于匹配需要屏蔽请求 Body 的字符串 | +| blocked_code | number | 选填 | 403 | 配置请求被屏蔽时返回的 HTTP 状态码 | +| blocked_message | string | 选填 | - | 配置请求被屏蔽时返回的 HTTP 应答 Body | +| case_sensitive | bool | 选填 | true | 配置匹配时是否区分大小写,默认区分 | + +# 配置示例 + +## 屏蔽请求 url 路径 +```yaml +block_urls: +- swagger.html +- foo=bar +case_sensitive: false +``` + +根据该配置,下列请求将被禁止访问: + +```bash +curl http://example.com?foo=Bar +curl http://exmaple.com/Swagger.html +``` + +## 屏蔽请求 header +```yaml +block_headers: +- example-key +- example-value +``` + +根据该配置,下列请求将被禁止访问: + +```bash +curl http://example.com -H 'example-key: 123' +curl http://exmaple.com -H 'my-header: example-value' +``` + +## 屏蔽请求 body +```yaml +block_bodys: +- "hello world" +case_sensitive: false +``` + +根据该配置,下列请求将被禁止访问: + +```bash +curl http://example.com -d 'Hello World' +curl http://exmaple.com -d 'hello world' +``` + +## 对特定路由或域名开启 +```yaml +# 使用 _rules_ 字段进行细粒度规则配置 +_rules_: +# 规则一:按路由名称匹配生效 +- _match_route_: + - route-a + - route-b + block_bodys: + - "hello world" +# 规则二:按域名匹配生效 +- _match_domain_: + - "*.example.com" + - test.com + block_urls: + - "swagger.html" + block_bodys: + - "hello world" +``` +此例 `_match_route_` 中指定的 `route-a` 和 `route-b` 即在创建网关路由时填写的路由名称,当匹配到这两个路由时,将使用此段配置; +此例 `_match_domain_` 中指定的 `*.example.com` 和 `test.com` 用于匹配请求的域名,当发现域名匹配时,将使用此段配置; +配置的匹配生效顺序,将按照 `_rules_` 下规则的排列顺序,匹配第一个规则后生效对应配置,后续规则将被忽略。 + +# 请求 Body 大小限制 + +当配置了 `block_bodys` 时,仅支持小于 32 MB 的请求 Body 进行匹配。若请求 Body 大于此限制,并且不存在匹配到的 `block_urls` 和 `block_headers` 项时,不会对该请求执行屏蔽操作 +当配置了 `block_bodys` 时,若请求 Body 超过全局配置 DownstreamConnectionBufferLimits,将返回 `413 Payload Too Large` diff --git a/plugins/wasm-go/extensions/request-block/VERSION b/plugins/wasm-go/extensions/request-block/VERSION new file mode 100644 index 000000000..afaf360d3 --- /dev/null +++ b/plugins/wasm-go/extensions/request-block/VERSION @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file