From 518da4e244d96e1d5ce522c572f69997f344df26 Mon Sep 17 00:00:00 2001 From: chnliyong Date: Mon, 12 Aug 2019 07:29:21 +0000 Subject: [PATCH 1/5] Add IP whitelist/blacklist plugin ip-restriction --- lua/apisix/plugins/ip-restriction.lua | 112 +++++++++++++ rockspec/apisix-dev-1.0-0.rockspec | 1 + t/plugin/ip-restriction.t | 225 ++++++++++++++++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 lua/apisix/plugins/ip-restriction.lua create mode 100644 t/plugin/ip-restriction.t diff --git a/lua/apisix/plugins/ip-restriction.lua b/lua/apisix/plugins/ip-restriction.lua new file mode 100644 index 000000000000..49669853ba61 --- /dev/null +++ b/lua/apisix/plugins/ip-restriction.lua @@ -0,0 +1,112 @@ +-- Ref: https://github.com/Kong/kong/blob/master/kong/plugins/ip-restriction + +local core = require("apisix.core") +local iputils = require("resty.iputils") + +local schema = { + type = "object", + properties = { + whitelist = { + type = "array", + items = {type = "string"}, + minItems = 1 + }, + blacklist = { + type = "array", + items = {type = "string"}, + minItems = 1 + } + }, + oneOf = { + {required = {"whitelist"}}, + {required = {"blacklist"}} + } +} + + +local plugin_name = "ip-restriction" + +local _M = { + version = 0.1, + priority = 3000, -- TODO: add a type field, may be a good idea + name = plugin_name, + schema = schema, +} + + +local FORBIDDEN = 403 +local cache = {} + + +local function cidr_cache(cidr_tab) + local cidr_tab_len = #cidr_tab + + -- table of parsed cidrs to return + local parsed_cidrs = core.table.new(cidr_tab_len, 0) + + -- build a table of parsed cidr blocks based on configured + -- cidrs, either from cache or via iputils parse + for i = 1, cidr_tab_len do + local cidr = cidr_tab[i] + local parsed_cidr = cache[cidr] + + if parsed_cidr then + parsed_cidrs[i] = parsed_cidr + else + -- if we dont have this cidr block cached, + -- parse it and cache the results + local lower, upper = iputils.parse_cidr(cidr) + + cache[cidr] = { lower, upper } + parsed_cidrs[i] = cache[cidr] + end + end + + return parsed_cidrs +end + + +function _M.init() + local ok, err = iputils.enable_lrucache() + if not ok then + core.log.error("could not enable lrucache: ", err) + end +end + + +function _M.check_schema(conf) + local ok, err = core.schema.check(schema, conf) + + if not ok then + return false, err + end + + return true +end + + +function _M.access(conf, ctx) + local block = false + local binary_remote_addr = ctx.var.binary_remote_addr + + if not binary_remote_addr then + return FORBIDDEN, { message = "Cannot identify the client IP address, unix domain sockets are not supported." } + end + + if conf.blacklist and #conf.blacklist > 0 then + block = iputils.binip_in_cidrs(binary_remote_addr, + cidr_cache(conf.blacklist)) + end + + if conf.whitelist and #conf.whitelist > 0 then + block = not iputils.binip_in_cidrs(binary_remote_addr, + cidr_cache(conf.whitelist)) + end + + if block then + return FORBIDDEN, { message = "Your IP address is not allowed" } + end +end + + +return _M diff --git a/rockspec/apisix-dev-1.0-0.rockspec b/rockspec/apisix-dev-1.0-0.rockspec index 8c13462362d9..256533fadd55 100644 --- a/rockspec/apisix-dev-1.0-0.rockspec +++ b/rockspec/apisix-dev-1.0-0.rockspec @@ -29,6 +29,7 @@ dependencies = { "lua-resty-openidc = 1.7.2", "opentracing-openresty = 0.1", "lua-resty-radixtree = 0.4", + "lua-resty-iputils = 0.3.0-1", } build = { diff --git a/t/plugin/ip-restriction.t b/t/plugin/ip-restriction.t new file mode 100644 index 000000000000..f3868c4f0670 --- /dev/null +++ b/t/plugin/ip-restriction.t @@ -0,0 +1,225 @@ +use t::APISix 'no_plan'; + +repeat_each(1); +no_root_location(); +no_shuffle(); + +sub read_file($) { + my $infile = shift; + open my $in, $infile + or die "cannot open $infile for reading: $!"; + my $cert = do { local $/; <$in> }; + close $in; + $cert; +} + +our $yaml_config = read_file("conf/config.yaml"); +$yaml_config =~ s/node_listen: 9080/node_listen: 1984/; +$yaml_config =~ s/enable_heartbeat: true/enable_heartbeat: false/; +$yaml_config =~ s/- example-plugin/- ip-restriction/; + +run_tests; + + +__DATA__ + +=== TEST 1: sanity +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.ip-restriction") + local conf = { + whitelist = { + "10.255.254.0/24", + "192.168.0.0/16" + } + } + local ok, err = plugin.check_schema(conf) + if not ok then + ngx.say(err) + end + + ngx.say(require("cjson").encode(conf)) + } + } +--- request +GET /t +--- response_body +{"whitelist":["10.255.254.0\/24","192.168.0.0\/16"]} +--- no_error_log +[error] + + + +=== TEST 2: empty conf +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.ip-restriction") + + local ok, err = plugin.check_schema({}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +invalid "oneOf" in docuement at pointer "#" +done +--- no_error_log +[error] + + +=== TEST 3: empty CIDRs +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.ip-restriction") + + local ok, err = plugin.check_schema({blacklist={}}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +invalid "type" in docuement at pointer "#/blacklist" +done +--- no_error_log +[error] + + + +=== TEST 4: whitelist and blacklist mutual exclusive +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.ip-restriction") + local ok, err = plugin.check_schema({whitelist={"172.17.40.0/24"}, blacklist={"10.255.0.0/16"}}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +invalid "oneOf" in docuement at pointer "#" +done +--- no_error_log +[error] + + +=== TEST 5: set route(id: 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/server_port", + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + }, + "plugins": { + "ip-restriction": { + "whitelist": [ + "127.0.0.0/24" + ] + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- yaml_config eval +$::yaml_config +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 6: hit route +--- request +GET /server_port +--- response_body_like eval +qr/1980/ +--- no_error_log +[error] + + +=== TEST 7: set route(id: 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/server_port", + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + }, + "plugins": { + "ip-restriction": { + "blacklist": [ + "127.0.0.0/24" + ] + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- yaml_config eval +$::yaml_config +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 8: hit route +--- request +GET /server_port +--- yaml_config eval +$::yaml_config +--- error_code: 403 +--- response_body +{"message":"Your IP address is not allowed"} +--- no_error_log +[error] From b9ab31b8a087f519eaea9e3a4fe8172efb4f8471 Mon Sep 17 00:00:00 2001 From: chnliyong Date: Mon, 12 Aug 2019 08:00:15 +0000 Subject: [PATCH 2/5] Add CIDRv4 format check --- COPYRIGHT | 27 +++ conf/config.yaml | 1 + lua/apisix/plugins/ip-restriction.lua | 42 +++- t/plugin/ip-restriction.t | 263 ++++++++++++++++++++++---- 4 files changed, 287 insertions(+), 46 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index ad8a171d9dd2..d0290c406358 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -280,3 +280,30 @@ See the License for the specific language governing permissions and limitations under the License. %%%%%%%%% + +lua-resty-iputils + +https://github.com/hamishforbes/lua-resty-iputils + +The MIT License (MIT) + +Copyright (c) 2013 Hamish Forbes + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +%%%%%%%%% diff --git a/conf/config.yaml b/conf/config.yaml index 4dc63429df53..a6595ffa601d 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -32,3 +32,4 @@ plugins: # plugin list - node-status - jwt-auth - zipkin + - ip-restriction diff --git a/lua/apisix/plugins/ip-restriction.lua b/lua/apisix/plugins/ip-restriction.lua index 49669853ba61..bc98b525281d 100644 --- a/lua/apisix/plugins/ip-restriction.lua +++ b/lua/apisix/plugins/ip-restriction.lua @@ -1,8 +1,9 @@ --- Ref: https://github.com/Kong/kong/blob/master/kong/plugins/ip-restriction +local ipairs = ipairs local core = require("apisix.core") local iputils = require("resty.iputils") + local schema = { type = "object", properties = { @@ -33,11 +34,20 @@ local _M = { schema = schema, } - -local FORBIDDEN = 403 local cache = {} +-- TODO: support IPv6 +local function validate_cidr_v4(ip) + local lower, err = iputils.parse_cidr(ip) + if not lower and err then + return nil, "invalid cidr range: " .. err + end + + return true +end + + local function cidr_cache(cidr_tab) local cidr_tab_len = #cidr_tab @@ -69,7 +79,7 @@ end function _M.init() local ok, err = iputils.enable_lrucache() if not ok then - core.log.error("could not enable lrucache: ", err) + core.log.error("could not enable lrucache for iputils: ", err) end end @@ -81,6 +91,24 @@ function _M.check_schema(conf) return false, err end + if conf.whitelist and #conf.whitelist > 0 then + for _, cidr in ipairs(conf.whitelist) do + ok, err = validate_cidr_v4(cidr) + if not ok then + return false, err + end + end + end + + if conf.blacklist and #conf.blacklist > 0 then + for _, cidr in ipairs(conf.blacklist) do + ok, err = validate_cidr_v4(cidr) + if not ok then + return false, err + end + end + end + return true end @@ -89,10 +117,6 @@ function _M.access(conf, ctx) local block = false local binary_remote_addr = ctx.var.binary_remote_addr - if not binary_remote_addr then - return FORBIDDEN, { message = "Cannot identify the client IP address, unix domain sockets are not supported." } - end - if conf.blacklist and #conf.blacklist > 0 then block = iputils.binip_in_cidrs(binary_remote_addr, cidr_cache(conf.blacklist)) @@ -104,7 +128,7 @@ function _M.access(conf, ctx) end if block then - return FORBIDDEN, { message = "Your IP address is not allowed" } + return 403, { message = "Your IP address is not allowed" } end end diff --git a/t/plugin/ip-restriction.t b/t/plugin/ip-restriction.t index f3868c4f0670..6025426156ea 100644 --- a/t/plugin/ip-restriction.t +++ b/t/plugin/ip-restriction.t @@ -1,26 +1,22 @@ +BEGIN { + if ($ENV{TEST_NGINX_CHECK_LEAK}) { + $SkipReason = "unavailable for the hup tests"; + + } else { + $ENV{TEST_NGINX_USE_HUP} = 1; + undef $ENV{TEST_NGINX_USE_STAP}; + } +} + use t::APISix 'no_plan'; repeat_each(1); -no_root_location(); +no_long_string(); no_shuffle(); - -sub read_file($) { - my $infile = shift; - open my $in, $infile - or die "cannot open $infile for reading: $!"; - my $cert = do { local $/; <$in> }; - close $in; - $cert; -} - -our $yaml_config = read_file("conf/config.yaml"); -$yaml_config =~ s/node_listen: 9080/node_listen: 1984/; -$yaml_config =~ s/enable_heartbeat: true/enable_heartbeat: false/; -$yaml_config =~ s/- example-plugin/- ip-restriction/; +no_root_location(); run_tests; - __DATA__ === TEST 1: sanity @@ -51,7 +47,63 @@ GET /t -=== TEST 2: empty conf +=== TEST 2: wrong CIDR v4 format +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.ip-restriction") + local conf = { + whitelist = { + "10.255.256.0/24", + "192.168.0.0/16" + } + } + local ok, err = plugin.check_schema(conf) + if not ok then + ngx.say(err) + end + + ngx.say(require("cjson").encode(conf)) + } + } +--- request +GET /t +--- response_body_like eval +qr/invalid cidr range: Invalid octet: 256/ +--- no_error_log +[error] + + + +=== TEST 3: wrong CIDR v4 format +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.ip-restriction") + local conf = { + whitelist = { + "10.255.254.0/38", + "192.168.0.0/16" + } + } + local ok, err = plugin.check_schema(conf) + if not ok then + ngx.say(err) + end + + ngx.say(require("cjson").encode(conf)) + } + } +--- request +GET /t +--- response_body_like eval +qr@invalid cidr range: Invalid prefix: /38@ +--- no_error_log +[error] + + + +=== TEST 4: empty conf --- config location /t { content_by_lua_block { @@ -74,7 +126,8 @@ done [error] -=== TEST 3: empty CIDRs + +=== TEST 5: empty CIDRs --- config location /t { content_by_lua_block { @@ -98,7 +151,7 @@ done -=== TEST 4: whitelist and blacklist mutual exclusive +=== TEST 6: whitelist and blacklist mutual exclusive --- config location /t { content_by_lua_block { @@ -120,7 +173,8 @@ done [error] -=== TEST 5: set route(id: 1) + +=== TEST 7: set whitelist --- config location /t { content_by_lua_block { @@ -128,7 +182,7 @@ done local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, [[{ - "uri": "/server_port", + "uri": "/hello", "upstream": { "type": "roundrobin", "nodes": { @@ -138,7 +192,8 @@ done "plugins": { "ip-restriction": { "whitelist": [ - "127.0.0.0/24" + "127.0.0.0/24", + "113.74.26.106" ] } } @@ -153,8 +208,6 @@ done } --- request GET /t ---- yaml_config eval -$::yaml_config --- response_body passed --- no_error_log @@ -162,16 +215,64 @@ passed -=== TEST 6: hit route +=== TEST 8: hit route and ip cidr in the whitelist --- request -GET /server_port ---- response_body_like eval -qr/1980/ +GET /hello +--- response_body +hello world --- no_error_log [error] -=== TEST 7: set route(id: 1) + +=== TEST 9: hit route and ip in the whitelist +--- http_config +set_real_ip_from 127.0.0.1; +real_ip_header X-Forwarded-For; +--- more_headers +X-Forwarded-For: 113.74.26.106 +--- request +GET /hello +--- response_body +hello world +--- no_error_log +[error] + + + +=== TEST 10: hit route and ip not in the whitelist +--- http_config +set_real_ip_from 127.0.0.1; +real_ip_header X-Forwarded-For; +--- more_headers +X-Forwarded-For: 114.114.114.114 +--- request +GET /hello +--- error_code: 403 +--- response_body +{"message":"Your IP address is not allowed"} +--- no_error_log +[error] + + + +=== TEST 11: hit route and ipv6 not not in the whitelist +--- http_config +set_real_ip_from 127.0.0.1; +real_ip_header X-Forwarded-For; +--- more_headers +X-Forwarded-For: 2001:db8::2 +--- request +GET /hello +--- error_code: 403 +--- response_body +{"message":"Your IP address is not allowed"} +--- no_error_log +[error] + + + +=== TEST 12: set blacklist --- config location /t { content_by_lua_block { @@ -179,7 +280,7 @@ qr/1980/ local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, [[{ - "uri": "/server_port", + "uri": "/hello", "upstream": { "type": "roundrobin", "nodes": { @@ -189,7 +290,8 @@ qr/1980/ "plugins": { "ip-restriction": { "blacklist": [ - "127.0.0.0/24" + "127.0.0.0/24", + "113.74.26.106" ] } } @@ -204,8 +306,6 @@ qr/1980/ } --- request GET /t ---- yaml_config eval -$::yaml_config --- response_body passed --- no_error_log @@ -213,13 +313,102 @@ passed -=== TEST 8: hit route +=== TEST 13: hit route and ip cidr in the blacklist +--- request +GET /hello +--- error_code: 403 +--- response_body +{"message":"Your IP address is not allowed"} +--- no_error_log +[error] + + + +=== TEST 14: hit route and ip in the blacklist +--- http_config +set_real_ip_from 127.0.0.1; +real_ip_header X-Forwarded-For; +--- more_headers +X-Forwarded-For: 113.74.26.106 --- request -GET /server_port ---- yaml_config eval -$::yaml_config +GET /hello --- error_code: 403 --- response_body {"message":"Your IP address is not allowed"} --- no_error_log [error] + + + +=== TEST 15: hit route and ip not not in the blacklist +--- http_config +set_real_ip_from 127.0.0.1; +real_ip_header X-Forwarded-For; +--- more_headers +X-Forwarded-For: 114.114.114.114 +--- request +GET /hello +--- response_body +hello world +--- no_error_log +[error] + + + +=== TEST 16: hit route and ipv6 not not in the blacklist +--- http_config +set_real_ip_from 127.0.0.1; +real_ip_header X-Forwarded-For; +--- more_headers +X-Forwarded-For: 2001:db8::2 +--- request +GET /hello +--- response_body +hello world +--- no_error_log +[error] + + + +=== TEST 17: remove ip-restriction +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/hello", + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + }, + "plugins": { + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 18: hit route +--- request +GET /hello +--- response_body +hello world +--- no_error_log +[error] From 31eb5141083be775e12f9b7d079483eac5241312 Mon Sep 17 00:00:00 2001 From: WenMing Date: Mon, 19 Aug 2019 12:36:45 +0800 Subject: [PATCH 3/5] used the lurcache. --- lua/apisix/plugins/ip-restriction.lua | 66 ++++++++++----------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/lua/apisix/plugins/ip-restriction.lua b/lua/apisix/plugins/ip-restriction.lua index bc98b525281d..f88ddf5d31a5 100644 --- a/lua/apisix/plugins/ip-restriction.lua +++ b/lua/apisix/plugins/ip-restriction.lua @@ -27,6 +27,7 @@ local schema = { local plugin_name = "ip-restriction" + local _M = { version = 0.1, priority = 3000, -- TODO: add a type field, may be a good idea @@ -34,8 +35,6 @@ local _M = { schema = schema, } -local cache = {} - -- TODO: support IPv6 local function validate_cidr_v4(ip) @@ -48,42 +47,6 @@ local function validate_cidr_v4(ip) end -local function cidr_cache(cidr_tab) - local cidr_tab_len = #cidr_tab - - -- table of parsed cidrs to return - local parsed_cidrs = core.table.new(cidr_tab_len, 0) - - -- build a table of parsed cidr blocks based on configured - -- cidrs, either from cache or via iputils parse - for i = 1, cidr_tab_len do - local cidr = cidr_tab[i] - local parsed_cidr = cache[cidr] - - if parsed_cidr then - parsed_cidrs[i] = parsed_cidr - else - -- if we dont have this cidr block cached, - -- parse it and cache the results - local lower, upper = iputils.parse_cidr(cidr) - - cache[cidr] = { lower, upper } - parsed_cidrs[i] = cache[cidr] - end - end - - return parsed_cidrs -end - - -function _M.init() - local ok, err = iputils.enable_lrucache() - if not ok then - core.log.error("could not enable lrucache for iputils: ", err) - end -end - - function _M.check_schema(conf) local ok, err = core.schema.check(schema, conf) @@ -113,18 +76,37 @@ function _M.check_schema(conf) end +local function create_cidrs(ip_list) + local parsed_cidrs = core.table.new(#ip_list, 0) + for i, cidr in ipairs(ip_list) do + local lower, upper = iputils.parse_cidr(cidr) + if not lower and upper then + local err = upper + return nil, "invalid cidr range: " .. err + end + parsed_cidrs[i] = {lower, upper} + end + + return parsed_cidrs +end + + function _M.access(conf, ctx) local block = false local binary_remote_addr = ctx.var.binary_remote_addr if conf.blacklist and #conf.blacklist > 0 then - block = iputils.binip_in_cidrs(binary_remote_addr, - cidr_cache(conf.blacklist)) + local name = plugin_name .. 'black' + local parsed_cidrs = core.lrucache.plugin_ctx(name, ctx, create_cidrs, + conf.blacklist) + block = iputils.binip_in_cidrs(binary_remote_addr, parsed_cidrs) end if conf.whitelist and #conf.whitelist > 0 then - block = not iputils.binip_in_cidrs(binary_remote_addr, - cidr_cache(conf.whitelist)) + local name = plugin_name .. 'white' + local parsed_cidrs = core.lrucache.plugin_ctx(name, ctx, create_cidrs, + conf.whitelist) + block = not iputils.binip_in_cidrs(binary_remote_addr, parsed_cidrs) end if block then From d4e22cef4584689f441049a17304240f91e75ecc Mon Sep 17 00:00:00 2001 From: WenMing Date: Mon, 19 Aug 2019 12:41:09 +0800 Subject: [PATCH 4/5] fixed test cases. --- t/admin/plugins.t | 2 +- t/debug-mode.t | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/t/admin/plugins.t b/t/admin/plugins.t index 573d2126be86..45f1cc046b00 100644 --- a/t/admin/plugins.t +++ b/t/admin/plugins.t @@ -14,6 +14,6 @@ __DATA__ --- request GET /apisix/admin/plugins/list --- response_body_like eval -qr/\["limit-req","limit-count","limit-conn","key-auth","prometheus","node-status","jwt-auth","zipkin"\]/ +qr/\["limit-req","limit-count","limit-conn","key-auth","prometheus","node-status","jwt-auth","zipkin","ip-restriction"\]/ --- no_error_log [error] diff --git a/t/debug-mode.t b/t/debug-mode.t index 3f56ff63a897..16c48720a55c 100644 --- a/t/debug-mode.t +++ b/t/debug-mode.t @@ -39,6 +39,7 @@ done --- grep_error_log eval qr/loaded plugin and sort by priority: [-\d]+ name: [\w-]+/ --- grep_error_log_out +loaded plugin and sort by priority: 3000 name: ip-restriction loaded plugin and sort by priority: 2510 name: jwt-auth loaded plugin and sort by priority: 2500 name: key-auth loaded plugin and sort by priority: 1003 name: limit-conn From dc90a32a0c28dc5b74c15096f7aece0b5e7897ad Mon Sep 17 00:00:00 2001 From: WenMing Date: Mon, 19 Aug 2019 12:46:17 +0800 Subject: [PATCH 5/5] added feature in readme. --- README.md | 3 ++- README_CN.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b1a21f06cb4a..2745af9591b9 100644 --- a/README.md +++ b/README.md @@ -52,10 +52,11 @@ For more detailed information, see the [White Paper](https://www.iresty.com/down - **Scalability** - **High performance**: The single-core QPS reaches 24k with an average delay of less than 0.6 milliseconds. - **Anti-ReDoS(Regular expression Denial of Service)** +- **IP whitelist/blacklist** - **OAuth2.0**: TODO. - **ACL**: TODO. - **Bot detection**: TODO. -- **IP blacklist**: TODO. + ## Install diff --git a/README_CN.md b/README_CN.md index bb649b0acced..488457732b5a 100644 --- a/README_CN.md +++ b/README_CN.md @@ -49,10 +49,10 @@ APISIX 通过插件机制,提供动态负载平衡、身份验证、限流限 - **可扩展** - **高性能**:在单核上 QPS 可以达到 24k,同时延迟只有 0.6 毫秒。 - **防御 ReDoS(正则表达式拒绝服务)** +- **IP 黑名单** - **OAuth2.0**: TODO. - **ACL**: TODO. - **Bot detection**: TODO. -- **IP 黑名单**: TODO. ## 安装