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

feat(ip-restriction): Add TCP Support #10245

Merged
merged 55 commits into from Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
06ea6ac
feat(ip-restriction): Add TCP Support
scrudge Feb 6, 2023
06d3261
Merge branch 'Kong:master' into master
scrudge Feb 8, 2023
4d281a7
feat(ip-restriction): Localize json conversion and string formatting
scrudge Feb 8, 2023
0cf7888
Merge branch 'Kong:master' into master
scrudge Feb 11, 2023
929dbb0
Merge branch 'Kong:master' into master
scrudge Feb 15, 2023
6aa987e
Merge branch 'Kong:master' into master
scrudge Feb 19, 2023
fef1b7d
feat(ip-restriction): localize cjson and tcpsock
scrudge Feb 19, 2023
808353a
feat(ip-restriction): fix tests
scrudge Feb 19, 2023
73df543
feat(ip-restriction): Use string to report IP, localize exit and ret…
scrudge Feb 20, 2023
08fa05c
Merge branch 'Kong:master' into master
scrudge Feb 20, 2023
23b3cf6
feat(ip-restriction): Set exit code to status
scrudge Feb 22, 2023
a216f67
Merge branch 'Kong:master' into master
scrudge Feb 22, 2023
06bffe0
feat(ip-restriction): Remove status from TCP response
scrudge Feb 23, 2023
333fbfb
Merge branch 'Kong:master' into master
scrudge Feb 23, 2023
12c11da
Merge branch 'Kong:master' into master
scrudge Feb 23, 2023
d1c7501
Update kong/plugins/ip-restriction/handler.lua
scrudge Mar 8, 2023
8123cce
Update kong/plugins/ip-restriction/handler.lua
scrudge Mar 8, 2023
63f4f19
Merge branch 'Kong:master' into master
scrudge Mar 13, 2023
dc94b55
Merge branch 'Kong:master' into master
scrudge Apr 28, 2023
605fa76
wip: add tests for tcp ip restriction plugin
jjchambl Jun 13, 2023
e5635c4
Merge branch 'Kong:master' into master
scrudge Jun 13, 2023
becec8f
Merge branch 'Kong:master' into master
scrudge Jun 14, 2023
b097631
Merge branch 'Kong:master' into master
scrudge Jun 14, 2023
1591e5e
Merge pull request #1 from jjchambl/feat/tcp_ip_restriction
scrudge Jun 14, 2023
54df200
Merge branch 'master' into master
scrudge Jun 15, 2023
d1d5794
test(ip-restrictions): Correct CIDRs
scrudge Jun 15, 2023
cc56a33
test(ip-restriction): Fix CIDRs
scrudge Jun 15, 2023
75f7973
feat(ip-restrction): Remove uneeded variables
scrudge Jun 15, 2023
17bf82b
test(ip-restriction): Add IP to stream_listen
scrudge Jun 15, 2023
218f184
test(ip-restriction): Update syntax on stream_listen
scrudge Jun 15, 2023
6c3ee61
test(ip-restrictions): Add assert matches
scrudge Jun 15, 2023
f6a294a
test(ip-restriction): Update matches assert
scrudge Jun 15, 2023
0b71f20
test(ip-restriction): Check raw body for substring
scrudge Jun 16, 2023
42eb3eb
test(ip-restriction): Convert to assert matches
scrudge Jun 16, 2023
f438025
doh!
scrudge Jun 16, 2023
af55d98
test(ip-restriction): convert assert to matches
scrudge Jun 16, 2023
5546de8
test(ip-restriction): convert assert to matches
scrudge Jun 16, 2023
68178a5
Update kong/plugins/ip-restriction/handler.lua
scrudge Jun 16, 2023
26849d3
fix(ip-restriction): rolback suggested change
scrudge Jun 16, 2023
d454899
fix(ip-restriction): Syntax error
scrudge Jun 16, 2023
4f7a747
Merge branch 'master' into master
scrudge Jun 21, 2023
84d4771
feat(ip-restriction): Remove json response from tcp exit
scrudge Jun 21, 2023
94e82cf
Merge branch 'Kong:master' into master
scrudge Jun 21, 2023
428b153
Merge branch 'master' into master
scrudge Jun 22, 2023
5b1f9d8
Merge branch 'master' into master
scrudge Jun 22, 2023
de2ecf2
Merge branch 'Kong:master' into master
scrudge Jun 27, 2023
7a1897f
feat(ip-restriction): Use kong.response.error for TCP
scrudge Jun 27, 2023
2e8eadd
feat(ip-restriction): Cleanup unused variables
scrudge Jun 27, 2023
d767c11
feat(ip-restriction): Revert kong response change
scrudge Jun 27, 2023
292a134
Merge branch 'Kong:master' into master
scrudge Jun 30, 2023
94c5dc6
feat(ip-restriction): Remove message from TCP deny
scrudge Jun 30, 2023
fe14d09
feat(ip-restriction): Apply lint suggestion
scrudge Jun 30, 2023
d89d257
Merge branch 'Kong:master' into master
scrudge Jul 3, 2023
9d1bd70
Merge branch 'Kong:master' into master
scrudge Jul 4, 2023
7a6d439
Merge branch 'Kong:master' into master
scrudge Jul 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 46 additions & 5 deletions kong/plugins/ip-restriction/handler.lua
@@ -1,9 +1,11 @@
local cjson = require "cjson.safe"
local lrucache = require "resty.lrucache"
local ipmatcher = require "resty.ipmatcher"
local kong_meta = require "kong.meta"


local ngx_var = ngx.var
local ngx_req = ngx.req
local kong = kong
local error = error

Expand All @@ -29,6 +31,31 @@ do
end


local is_http_subsystem = ngx.config.subsystem == "http"


local do_exit
if is_http_subsystem then
do_exit = function(status, message)
return kong.response.error(status, message)
end
else
scrudge marked this conversation as resolved.
Show resolved Hide resolved
do_exit = function(status, message)
local cjson_encode = cjson.encode
scrudge marked this conversation as resolved.
Show resolved Hide resolved
local tcpsock, err = ngx_req.socket(true)
if err then
error(err)
end

tcpsock:send(cjson_encode({
status = status,
message = message
scrudge marked this conversation as resolved.
Show resolved Hide resolved
}))

return ngx.exit()
scrudge marked this conversation as resolved.
Show resolved Hide resolved
end
end

local function match_bin(list, binary_remote_addr)
local matcher, err

Expand All @@ -52,31 +79,45 @@ local function match_bin(list, binary_remote_addr)
end


function IpRestrictionHandler:access(conf)
local function handler(conf)
scrudge marked this conversation as resolved.
Show resolved Hide resolved
local binary_remote_addr = ngx_var.binary_remote_addr
if not binary_remote_addr then
return kong.response.error(403, "Cannot identify the client IP address, unix domain sockets are not supported.")
local status = 403
local message = "Cannot identify the client IP address, unix domain sockets are not supported."
scrudge marked this conversation as resolved.
Show resolved Hide resolved

do_exit(status, message)
scrudge marked this conversation as resolved.
Show resolved Hide resolved
end

local deny = conf.deny
local allow = conf.allow
local status = conf.status or 403
local message = conf.message or "Your IP address is not allowed"
local default_message = string.format("IP address not allowed: %s", binary_remote_addr)
scrudge marked this conversation as resolved.
Show resolved Hide resolved
local message = conf.message or default_message
scrudge marked this conversation as resolved.
Show resolved Hide resolved

if not isempty(deny) then
local blocked = match_bin(deny, binary_remote_addr)
if blocked then
return kong.response.error(status, message)
do_exit(status, message)
scrudge marked this conversation as resolved.
Show resolved Hide resolved
end
end

if not isempty(allow) then
local allowed = match_bin(allow, binary_remote_addr)
if not allowed then
return kong.response.error(status, message)
do_exit(status, message)
scrudge marked this conversation as resolved.
Show resolved Hide resolved
end
end
end


function IpRestrictionHandler:access(conf)
return handler(conf)
end


function IpRestrictionHandler:preread(conf)
return handler(conf)
end


return IpRestrictionHandler
2 changes: 1 addition & 1 deletion kong/plugins/ip-restriction/schema.lua
Expand Up @@ -4,7 +4,7 @@ local typedefs = require "kong.db.schema.typedefs"
return {
name = "ip-restriction",
fields = {
{ protocols = typedefs.protocols_http },
{ protocols = typedefs.protocols { default = { "http", "https", "tcp", "tls", "grpc", "grpcs" } }, },
{ config = {
type = "record",
fields = {
Expand Down
42 changes: 21 additions & 21 deletions spec/03-plugins/17-ip-restriction/02-access_spec.lua
Expand Up @@ -248,7 +248,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use assert.matches() with the special pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you send a link to the docs for assert.matches()? I can't find it.

end)

it("blocks a request when the IP is denied with status/message", function()
Expand Down Expand Up @@ -310,7 +310,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("blocks an IP on a allowed CIDR range", function()
local res = assert(proxy_client:send {
Expand All @@ -322,7 +322,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("takes precedence over an allowed IP", function()
local res = assert(proxy_client:send {
Expand All @@ -334,7 +334,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("takes precedence over an allowed CIDR range", function()
local res = assert(proxy_client:send {
Expand All @@ -346,7 +346,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)

describe("X-Forwarded-For", function()
Expand Down Expand Up @@ -386,7 +386,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
end)
end)
Expand All @@ -402,7 +402,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("allows a allowed IP", function()
local res = assert(proxy_client:send {
Expand All @@ -426,7 +426,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("block with not allowed X-Forwarded-For header", function()
local res = assert(proxy_client:send {
Expand All @@ -439,7 +439,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("block with not allowed X-Forwarded-For header #grpc", function()
local ok, err = helpers.proxy_client_grpc(){
Expand Down Expand Up @@ -522,7 +522,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))

res = assert(admin_client:send {
method = "PATCH",
Expand Down Expand Up @@ -722,7 +722,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("allows a request when the IPv6 is not denied", function()
local res = assert(proxy_client:send {
Expand All @@ -748,7 +748,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("blocks an IPv6 on a allowed IPv6 CIDR range", function()
local res = assert(proxy_client:send {
Expand All @@ -761,7 +761,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("takes precedence over an allowed IPv6", function()
local res = assert(proxy_client:send {
Expand All @@ -774,7 +774,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("takes precedence over an allowed IPv6 CIDR range", function()
local res = assert(proxy_client:send {
Expand All @@ -786,7 +786,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
end)

Expand All @@ -802,7 +802,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("allows a allowed IPv6", function()
local res = assert(proxy_client:send {
Expand Down Expand Up @@ -865,7 +865,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))

res = assert(admin_client:send {
method = "PATCH",
Expand Down Expand Up @@ -1002,7 +1002,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("blocks with blocked complex X-Forwarded-For header", function()
local res = assert(proxy_client:send {
Expand All @@ -1015,7 +1015,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("allows with allowed complex X-Forwarded-For header", function()
local res = assert(proxy_client:send {
Expand Down Expand Up @@ -1044,7 +1044,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
it("allows with allowed X-Forwarded-For header", function()
local res = assert(proxy_client:send {
Expand Down Expand Up @@ -1083,7 +1083,7 @@ for _, strategy in helpers.each_strategy() do
})
local body = assert.res_status(403, res)
local json = cjson.decode(body)
assert.same({ message = "Your IP address is not allowed" }, json)
assert.is_true(string.find(json, "IP address not allowed"))
end)
end)
end)
Expand Down