Merge pull request #431 from gin-gitaxias/staging

FEATURE - scan client ports
This commit is contained in:
Théophile Diot 2023-04-05 10:58:57 +02:00 committed by GitHub
commit a1e44f6e4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 129 additions and 0 deletions

View File

@ -0,0 +1,36 @@
{
"id": "reversescan",
"order": 5,
"name": "Reverse scan",
"description": "Scan clients ports to detect proxies or servers.",
"version": "0.1",
"settings": {
"USE_REVERSE_SCAN": {
"context": "multisite",
"default": "no",
"help": "Enable scanning of clients ports and deny access if one is opened.",
"id": "use-reverse-scan",
"label": "Reverse scan",
"regex": "^(no|yes)$",
"type": "check"
},
"REVERSE_SCAN_PORTS": {
"context": "multisite",
"default": "22 80 443 3128 8000 8080",
"help": "List of port to scan when using reverse scan feature.",
"id": "reverse-scan-ports",
"label": "Reverse scan ports",
"regex": "^.*$",
"type": "text"
},
"REVERSE_SCAN_TIMEOUT": {
"context": "multisite",
"default": "500",
"help": "Specify the maximum timeout (in ms) when scanning a port.",
"id": "reverse-scan-timeout",
"label": "Reverse scan timeout",
"regex": "^.*$",
"type": "text"
}
}
}

View File

@ -0,0 +1,93 @@
local _M = {}
_M.__index = _M
local utils = require "utils"
local datastore = require "datastore"
local logger = require "logger"
local cjson = require "cjson"
function _M.new()
local self = setmetatable({}, _M)
return self, nil
end
function _M:access()
-- Check if access is needed
local access_needed, err = utils.get_variable("USE_REVERSE_SCAN")
if access_needed == nil then
return false, "can't get USE_REVERSE_SCAN setting from datastore : " .. err, nil, nil
end
if access_needed ~= "yes" then
return true, "reverse scan not activated", nil, nil
end
-- Get ports
local ports, err = utils.get_variable("REVERSE_SCAN_PORTS")
if ports == nil then
return false, "can't get REVERSE_SCAN_PORTS setting from datastore : " .. err, nil, nil
end
if ports == "" then
return true, "no port defined", nil, nil
end
-- Get timeout
local timeout, err = utils.get_variable("REVERSE_SCAN_TIMEOUT")
if timeout == nil then
return false, "can't get REVERSE_SCAN_TIMEOUT setting from datastore : " .. err, nil, nil
end
-- Loop on ports
for port in ports:gmatch("%S+") do
-- Check if the scan is already cached
local cached, err = self:is_in_cache(ngx.var.remote_addr .. ":" .. port)
if cached == nil then
return false, "error getting cache from datastore : " .. err, nil, nil
end
if cached == "open" then
return true, "port " .. port .. " is opened for IP " .. ngx.var.remote_addr, true, utils.get_deny_status()
elseif not cached then
-- Do the scan
local res, err = self:scan(ngx.var.remote_addr, tonumber(port), tonumber(timeout))
-- Cache the result
local ok, err = self:add_to_cache(ngx.var.remote_addr .. ":" .. port, res)
if not ok then
return false, "error updating cache from datastore : " .. err, nil, nil
end
-- Deny request if port is open
if res == "open" then
return true, "port " .. port .. " is opened for IP " .. ngx.var.remote_addr, true, utils.get_deny_status()
end
end
end
return nil, "no port open for IP " .. ngx.var.remote_addr, nil, nil
end
function _M:scan(ip, port, timeout)
local tcpsock = ngx.socket.tcp()
tcpsock:settimeout(timeout)
local ok, err = tcpsock:connect(ip, port)
tcpsock:close()
if not ok then
return "close", err
end
return "open", nil
end
function _M:is_in_cache(ele)
local res, err = datastore:get("plugin_reversescan_" .. ele)
if not res then
if err == "not found" then
return false, nil
end
return nil, err
end
return true, res
end
function _M:add_to_cache(ele, value)
local ok, err = datastore:set("plugin_reversescan_" .. ele, value, 86400)
if not ok then
return false, err
end
return true, nil
end
return _M