Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IPv4 whitelist/blacklist plugin ip-restriction #398

Merged
merged 5 commits into from
Aug 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions COPYRIGHT
Original file line number Diff line number Diff line change
Expand Up @@ -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.

%%%%%%%%%
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ APISIX 通过插件机制,提供动态负载平衡、身份验证、限流限
- **可扩展**
- **高性能**:在单核上 QPS 可以达到 24k,同时延迟只有 0.6 毫秒。
- **防御 ReDoS(正则表达式拒绝服务)**
- **IP 黑名单**
- **OAuth2.0**: TODO.
- **ACL**: TODO.
- **Bot detection**: TODO.
- **IP 黑名单**: TODO.

## 安装

Expand Down
1 change: 1 addition & 0 deletions conf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ plugins: # plugin list
- node-status
- jwt-auth
- zipkin
- ip-restriction
118 changes: 118 additions & 0 deletions lua/apisix/plugins/ip-restriction.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
local ipairs = ipairs

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 = {
moonming marked this conversation as resolved.
Show resolved Hide resolved
{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
moonming marked this conversation as resolved.
Show resolved Hide resolved
name = plugin_name,
schema = schema,
}


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


function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)

if not ok then
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)
moonming marked this conversation as resolved.
Show resolved Hide resolved
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


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
moonming marked this conversation as resolved.
Show resolved Hide resolved

if conf.blacklist and #conf.blacklist > 0 then
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
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
return 403, { message = "Your IP address is not allowed" }
end
end


return _M
1 change: 1 addition & 0 deletions rockspec/apisix-dev-1.0-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -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",
moonming marked this conversation as resolved.
Show resolved Hide resolved
}

build = {
Expand Down
2 changes: 1 addition & 1 deletion t/admin/plugins.t
Original file line number Diff line number Diff line change
Expand Up @@ -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]
1 change: 1 addition & 0 deletions t/debug-mode.t
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading