APISIX-URI-Blocker插件

URI-Blocker

黑名单插件

Chinese

Summary

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:

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

$ 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:

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.

--
-- 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)
    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

test