refactoring and various improvements
This commit is contained in:
parent
a9ce32c262
commit
937cd10eeb
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"id": "reverse_scan",
|
||||
"order": 999,
|
||||
"name": "ReverseScan",
|
||||
"description": "Scan user when they connect",
|
||||
"version": "0.1",
|
||||
"settings": {
|
||||
"USE_REVERSE_SCAN": {
|
||||
"context": "multisite",
|
||||
"default": "no",
|
||||
"help": "Enable the 'reverse_scan' feature to attempt establishing a TCP connection on a list of ports defined in 'PORT_SCAN'.",
|
||||
"id": "use-Reverse-scan",
|
||||
"label": "port scanning",
|
||||
"regex": "^(no|yes)$",
|
||||
"type": "check"
|
||||
|
||||
|
||||
},
|
||||
"REVERSE_SCAN_PORT_SCAN": {
|
||||
"context": "multisite",
|
||||
"default": "22 23 25 80 443 3389 1433 3306",
|
||||
"help": "Specify a list of ports to scan. Default is '22 23 25 80 443 3389 1433 3306'.",
|
||||
"id": "port_scanning",
|
||||
"label": "List of port that will be scanned",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
},
|
||||
"REVERSE_SCAN_TIMEOUT": {
|
||||
"context": "multisite",
|
||||
"default": "0.5",
|
||||
"help": "Specify the maximum timeout (in seconds) when scanning a port. Default is '0.5'.",
|
||||
"id": "timeout_scanning",
|
||||
"label": "Time before connection request is aborded",
|
||||
"regex": "^.*$",
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
local _M = {}
|
||||
_M.__index = _M
|
||||
|
||||
|
||||
local utils = require "utils"
|
||||
local datastore = require "datastore"
|
||||
local logger = require "logger"
|
||||
local cjson = require "cjson"
|
||||
local socket = require "socket"
|
||||
|
||||
function _M.new()
|
||||
local self = setmetatable({}, _M)
|
||||
return self, nil
|
||||
end
|
||||
|
||||
function _M:init()
|
||||
logger.log(ngx.NOTICE, "REVERSE_SCAN", "init called")
|
||||
-- Check if init is needed
|
||||
local init_needed, err = utils.has_variable("REVERSE_SCAN", "yes")
|
||||
if init_needed == nil then
|
||||
return false, err
|
||||
end
|
||||
if not init_needed then
|
||||
return true, "no service uses port_scanning, skipping init"
|
||||
end
|
||||
local data = {}
|
||||
-- Get variable --
|
||||
local value, err = utils.get_variable("PORT_SCAN")
|
||||
logger.log(ngx.NOTICE, "REVERSE_SCAN", "port = " .. value)
|
||||
for srv in value:gmatch("%S+") do
|
||||
table.insert(data , srv)
|
||||
end
|
||||
-- Load them into datastore
|
||||
local ok, err = datastore:set("plug_scan_port" ,cjson.encode(data))
|
||||
if not ok then
|
||||
return false, "can't store port list into datastore : " .. err
|
||||
end
|
||||
return true, "successfully loaded scan port"
|
||||
end
|
||||
|
||||
function _M:access()
|
||||
logger.log(ngx.NOTICE, "REVERSE_SCAN", "access called")
|
||||
-- Check if access is needed
|
||||
local scan_port, err = utils.get_variable("REVERSE_SCAN")
|
||||
|
||||
if scan_port ~= "yes" then
|
||||
return true, "Scan port not activated"
|
||||
end
|
||||
-- Check the cache
|
||||
local cached_ip, err = self:is_in_cache("ip" .. ngx.var.remote_addr)
|
||||
-- check for errors
|
||||
if cached_ip=="denied" then
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is suspicious : port open", true, utils.get_deny_status()
|
||||
elseif cached_ip=="clean" then
|
||||
return true , "Ip already scanned and is safe" , nil , nil
|
||||
elseif cached_ip ~= false then
|
||||
return false, err , nil , nil
|
||||
end
|
||||
--get port
|
||||
local data, err = datastore:get("plug_scan_port")
|
||||
if not data then
|
||||
return false, "can't get port list : " .. err, false, nil
|
||||
end
|
||||
local port_List = cjson.decode(data)
|
||||
|
||||
--call scan function
|
||||
local sus = nil
|
||||
for i = 1, #port_List do
|
||||
if _M:scan(port_List[i])==true then
|
||||
|
||||
sus = true
|
||||
self:add_to_cache("ip" .. ngx.var.remote_addr, "denied")
|
||||
|
||||
return nil, "client IP " .. ngx.var.remote_addr .. " is suspicious : port open", true, utils.get_deny_status()
|
||||
end
|
||||
end
|
||||
self:add_to_cache("ip" .. ngx.var.remote_addr, "clean")
|
||||
return nil, "client IP " .. ngx.var.remote_addr .. " is safe ", true, nil
|
||||
end
|
||||
|
||||
function _M.scan(port)
|
||||
local client = socket.tcp()
|
||||
local time, err = utils.get_variable("TIMEOUT")
|
||||
client:settimeout(time)
|
||||
|
||||
local status, err = client:connect(ngx.var.remote_addr, port)
|
||||
if not status then
|
||||
local peername, peerport = client:getpeername()
|
||||
if not peername then
|
||||
--
|
||||
return false , err
|
||||
end
|
||||
end
|
||||
client:close()
|
||||
return true , err
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function _M:is_in_cache(ele)
|
||||
local kind, err = datastore:get("plug_scan_port" .. ngx.var.server_name .. ele)
|
||||
if not kind then
|
||||
if err ~= "not found" then
|
||||
logger.log(ngx.ERR, "REVERSE_SCAN", " Error while accessing cache : " .. err)
|
||||
end
|
||||
return false, err
|
||||
end
|
||||
return kind, "success"
|
||||
end
|
||||
|
||||
function _M:add_to_cache(ele, kind)
|
||||
local ok, err = datastore:set("plug_scan_port" .. ngx.var.server_name .. ele, kind, 3600)
|
||||
if not ok then
|
||||
logger.log(ngx.ERR, "REVERSE_SCAN", "Error while adding element to cache : " .. err)
|
||||
return false, err
|
||||
end
|
||||
return true, "success"
|
||||
end
|
||||
|
||||
|
||||
return _M
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 value: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
|
Loading…
Reference in New Issue