Skip to content

Commit

Permalink
feature: implemented plugin uri-blocklist . (#1727)
Browse files Browse the repository at this point in the history
first step: #1617
  • Loading branch information
membphis authored Jun 22, 2020
1 parent 748e337 commit 6a43a8c
Show file tree
Hide file tree
Showing 10 changed files with 460 additions and 5 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ A/B testing, canary release, blue-green deployment, limit rate, defense against
- [Limit-count](doc/plugins/limit-count.md)
- [Limit-concurrency](doc/plugins/limit-conn.md)
- Anti-ReDoS(Regular expression Denial of Service): Built-in policies to Anti ReDoS without configuration.
- [CORS](doc/plugins/cors.md)
- [CORS](doc/plugins/cors.md) Enable CORS(Cross-origin resource sharing) for your API.
- [uri-blocker](plugins/uri-blocker.md): Block client request by URI.

- **OPS friendly**
- OpenTracing: support [Apache Skywalking](doc/plugins/skywalking.md) and [Zipkin](doc/plugins/zipkin.md)
Expand Down
3 changes: 2 additions & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ A/B 测试、金丝雀发布(灰度发布)、蓝绿部署、限流限速、抵
- [限制请求数](doc/zh-cn/plugins/limit-count.md)
- [限制并发](doc/zh-cn/plugins/limit-conn.md)
- 防御 ReDoS(正则表达式拒绝服务):内置策略,无需配置即可抵御 ReDoS。
- [CORS](doc/zh-cn/plugins/cors.md)
- [CORS](doc/zh-cn/plugins/cors.md):为你的API启用 CORS。
- [uri-blocker](plugins/uri-blocker.md):根据 URI 拦截用户请求。

- **运维友好**
- OpenTracing 可观测性: 支持 [Apache Skywalking](doc/zh-cn/plugins/skywalking.md)[Zipkin](doc/zh-cn/plugins/zipkin.md)
Expand Down
86 changes: 86 additions & 0 deletions apisix/plugins/uri-blocker.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You 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.
--
local core = require("apisix.core")
local re_compile = require("resty.core.regex").re_match_compile
local re_find = ngx.re.find
local ipairs = ipairs

local schema = {
type = "object",
properties = {
block_rules = {
type = "array",
items = {
type = "string",
minLength = 1,
maxLength = 4096,
},
uniqueItems = true
},
rejected_code = {
type = "integer",
minimum = 200,
default = 403
},
},
required = {"block_rules"},
}


local plugin_name = "uri-blocker"

local _M = {
version = 0.1,
priority = 2900,
name = plugin_name,
schema = schema,
}


function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)
if not ok then
return false, err
end

local block_rules = {}
for i, re_rule in ipairs(conf.block_rules) do
local ok, err = re_compile(re_rule, "j")
-- core.log.warn("ok: ", tostring(ok), " err: ", tostring(err), " re_rule: ", re_rule)
if not ok then
return false, err
end
block_rules[i] = re_rule
end

conf.block_rules_concat = core.table.concat(block_rules, "|")
core.log.info("concat block_rules: ", conf.block_rules_concat)
return true
end


function _M.rewrite(conf, ctx)
core.log.info("uri: ", ctx.var.request_uri)
core.log.info("block uri rules: ", conf.block_rules_concat)
local from = re_find(ctx.var.request_uri, conf.block_rules_concat, "jo")
if from then
core.response.exit(conf.rejected_code)
end
end


return _M
3 changes: 2 additions & 1 deletion conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ apisix:
ssl_ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
key_encrypt_salt: "edd1c9f0985e76a2" # If not set, will save origin ssl key into etcd.
# If set this, must be a string of length 16. And it will encrypt ssl key with AES-128-CBC
# !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !!
# !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !!
# discovery: eureka # service discovery center
nginx_config: # config for render the template to genarate nginx.conf
error_log: "logs/error.log"
Expand Down Expand Up @@ -168,6 +168,7 @@ plugins: # plugin list
- skywalking
- echo
- authz-keycloak
- uri-blocker

stream_plugins:
- mqtt-proxy
4 changes: 3 additions & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ Plugins
* [kafka-logger](plugins/kafka-logger.md): Log requests to External Kafka servers.
* [cors](plugins/cors.md): Enable CORS(Cross-origin resource sharing) for your API.
* [batch-requests](plugins/batch-requests.md): Allow you send mutiple http api via **http pipeline**.
* [authz-keycloak](plugins/authz-keycloak.md): Authorization with Keycloak Identity Server
* [authz-keycloak](plugins/authz-keycloak.md): Authorization with Keycloak Identity Server.
* [uri-blocker](plugins/uri-blocker.md): Block client request by URI.

Deploy to the Cloud
=======

### AWS

The recommended approach is to deploy APISIX with [AWS CDK](https://aws.amazon.com/cdk/) on [AWS Fargate](https://aws.amazon.com/fargate/) which helps you decouple the APISIX layer and the upstream layer on top of a fully-managed and secure serverless container compute environment with autoscaling capabilities.
Expand Down
96 changes: 96 additions & 0 deletions doc/plugins/uri-blocker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.
#
-->

[Chinese](uri-blocker.md)

# Summary

- [**Name**](#name)
- [**Attributes**](#attributes)
- [**How To Enable**](#how-to-enable)
- [**Test Plugin**](#test-plugin)
- [**Disable Plugin**](#disable-plugin)

## Name

The plugin helps we intercept user requests, we only need to indicate the `block_rules`.

## Attributes

|Name |Requirement |Description|
|--------- |--------|-----------|
|block_rules |required|Regular filter rule array. Each of these items is a regular rule. If the current request URI hits any one of them, set the response code to rejected_code to exit the current user request. Example: `["root.exe", "root.m+"]`.|
|rejected_code |optional|The HTTP status code returned when the request URI hit any of `filter_rule`, default `403`.|

## How To Enable

Here's an example, enable the `uri blocker` plugin on the specified route:

```shell
curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/*",
"plugins": {
"uri-blocker": {
"block_rules": ["root.exe", "root.m+"]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```

## Test Plugin

```shell
$ curl -i http://127.0.0.1:9080/root.exe?a=a
HTTP/1.1 403 Forbidden
Date: Wed, 17 Jun 2020 13:55:41 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 150
Connection: keep-alive
Server: APISIX web server

... ...
```

## Disable Plugin

When you want to disable the `uri blocker` plugin, it is very simple,
you can delete the corresponding json configuration in the plugin configuration,
no need to restart the service, it will take effect immediately:

```shell
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/*",
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```

The `uri blocker` plugin has been disabled now. It works for other plugins.
1 change: 1 addition & 0 deletions doc/zh-cn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ Reference document
* [cors](plugins/cors.md): 为你的API启用 CORS
* [batch-requests](plugins/batch-requests.md): 以 **http pipeline** 的方式在网关一次性发起多个 `http` 请求。
* [authz-keycloak](plugins/authz-keycloak-cn.md): 支持 Keycloak 身份认证服务器
* [uri-blocker](plugins/uri-blocker.md): 根据 URI 拦截用户请求。
2 changes: 1 addition & 1 deletion t/admin/plugins.t
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ __DATA__
--- request
GET /apisix/admin/plugins/list
--- response_body_like eval
qr/\["limit-req","limit-count","limit-conn","key-auth","basic-auth","prometheus","node-status","jwt-auth","zipkin","ip-restriction","grpc-transcode","serverless-pre-function","serverless-post-function","openid-connect","proxy-rewrite","redirect","response-rewrite","fault-injection","udp-logger","wolf-rbac","proxy-cache","tcp-logger","proxy-mirror","kafka-logger","cors","consumer-restriction","syslog","batch-requests","http-logger","skywalking","echo","authz-keycloak"\]/
qr/\["limit-req","limit-count","limit-conn","key-auth","basic-auth","prometheus","node-status","jwt-auth","zipkin","ip-restriction","grpc-transcode","serverless-pre-function","serverless-post-function","openid-connect","proxy-rewrite","redirect","response-rewrite","fault-injection","udp-logger","wolf-rbac","proxy-cache","tcp-logger","proxy-mirror","kafka-logger","cors","consumer-restriction","syslog","batch-requests","http-logger","skywalking","echo","authz-keycloak","uri-blocker"\]/
--- no_error_log
[error]
Expand Down
1 change: 1 addition & 0 deletions t/debug/debug-mode.t
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ loaded plugin and sort by priority: 10000 name: serverless-pre-function
loaded plugin and sort by priority: 4010 name: batch-requests
loaded plugin and sort by priority: 4000 name: cors
loaded plugin and sort by priority: 3000 name: ip-restriction
loaded plugin and sort by priority: 2900 name: uri-blocker
loaded plugin and sort by priority: 2599 name: openid-connect
loaded plugin and sort by priority: 2555 name: wolf-rbac
loaded plugin and sort by priority: 2520 name: basic-auth
Expand Down
Loading

0 comments on commit 6a43a8c

Please sign in to comment.