bunkerweb 1.4.0
This commit is contained in:
136
core/dnsbl/dnsbl.lua
Normal file
136
core/dnsbl/dnsbl.lua
Normal file
@@ -0,0 +1,136 @@
|
||||
local _M = {}
|
||||
_M.__index = _M
|
||||
|
||||
local utils = require "utils"
|
||||
local datastore = require "datastore"
|
||||
local logger = require "logger"
|
||||
local cjson = require "cjson"
|
||||
local resolver = require "resty.dns.resolver"
|
||||
|
||||
function _M.new()
|
||||
local self = setmetatable({}, _M)
|
||||
return self, nil
|
||||
end
|
||||
|
||||
function _M:init()
|
||||
-- Check if init is needed
|
||||
local init_needed, err = utils.has_variable("USE_DNSBL", "yes")
|
||||
if init_needed == nil then
|
||||
return false, "can't check USE_DNS variable : " .. err
|
||||
end
|
||||
if not init_needed then
|
||||
return true, "no service uses Blacklist, skipping init"
|
||||
end
|
||||
-- Read DNSBL list
|
||||
local str_dnsbls, err = utils.get_variable("DNSBL_LIST", false)
|
||||
if not str_dnsbls then
|
||||
return false, "can't get DNSBL_LIST variable : " .. err
|
||||
end
|
||||
local dnsbls = {}
|
||||
local i = 0
|
||||
for dnsbl in str_dnsbls:gmatch("%S+") do
|
||||
table.insert(dnsbls, dnsbl)
|
||||
i = i + 1
|
||||
end
|
||||
-- Load it into datastore
|
||||
local ok, err = datastore:set("plugin_dnsbl_list", cjson.encode(dnsbls))
|
||||
if not ok then
|
||||
return false, "can't store DNSBL list into datastore : " .. err
|
||||
end
|
||||
return true, "successfully loaded " .. tostring(i) .. " DNSBL server(s)"
|
||||
end
|
||||
|
||||
function _M:access()
|
||||
-- Check if access is needed
|
||||
local access_needed, err = utils.get_variable("USE_DNSBL")
|
||||
if access_needed == nil then
|
||||
return false, err
|
||||
end
|
||||
if access_needed ~= "yes" then
|
||||
return true, "DNSBL not activated"
|
||||
end
|
||||
|
||||
-- Check if IP is in cache
|
||||
local dnsbl, err = self:is_in_cache(ngx.var.remote_addr)
|
||||
if dnsbl then
|
||||
if dnsbl == "ok" then
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in DNSBL cache (not blacklisted)", nil, nil
|
||||
end
|
||||
return true, "client IP " .. ngx.var.remote_addr .. " is in DNSBL cache (server = " .. dnsbl .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
end
|
||||
|
||||
-- Don't go further if IP is not global
|
||||
local is_global, err = utils.ip_is_global(ngx.var.remote_addr)
|
||||
if is_global == nil then
|
||||
return false, "can't check if client IP is global : " .. err, nil, nil
|
||||
end
|
||||
if not utils.ip_is_global(ngx.var.remote_addr) then
|
||||
self:add_to_cache(ngx.var.remote_addr, "ok")
|
||||
return true, "client IP is not global, skipping DNSBL check", nil, nil
|
||||
end
|
||||
|
||||
-- Get list
|
||||
local data, err = datastore:get("plugin_dnsbl_list")
|
||||
if not data then
|
||||
return false, "can't get DNSBL list : " .. err, false, nil
|
||||
end
|
||||
local ok, dnsbls = pcall(cjson.decode, data)
|
||||
if not ok then
|
||||
return false, "error while decoding DNSBL list : " .. dnsbls, false, nil
|
||||
end
|
||||
|
||||
-- Loop on dnsbl list
|
||||
for i, dnsbl in ipairs(dnsbls) do
|
||||
local result, err = self:is_in_dnsbl(dnsbl, ngx.var.remote_addr)
|
||||
if result then
|
||||
self:add_to_cache(ngx.var.remote_addr, dnsbl)
|
||||
return ret, "client IP " .. ngx.var.remote_addr .. " is in DNSBL (server = " .. dnsbl .. ")", true, ngx.HTTP_FORBIDDEN
|
||||
end
|
||||
end
|
||||
|
||||
-- IP is not in DNSBL
|
||||
local ok, err = self:add_to_cache(ngx.var.remote_addr, "ok")
|
||||
if not ok then
|
||||
return false, "IP is not in DNSBL (error = " .. err .. ")", false, nil
|
||||
end
|
||||
return true, "IP is not in DNSBL", false, nil
|
||||
|
||||
end
|
||||
|
||||
function _M:is_in_dnsbl(dnsbl, ip)
|
||||
local request = resolver.arpa_str(ip) .. "." .. dnsbl
|
||||
local ips, err = utils.get_ips(request)
|
||||
if not ips then
|
||||
logger.log(ngx.ERR, "DNSBL", "Error while asking DNSBL server " .. dnsbl .. " : " .. err)
|
||||
return false, err
|
||||
end
|
||||
for i, ip in ipairs(ips) do
|
||||
local a, b, c, d = ip:match("([%d]+).([%d]+).([%d]+).([%d]+)")
|
||||
if a == "127" then
|
||||
return true, "success"
|
||||
end
|
||||
end
|
||||
return false, "success"
|
||||
end
|
||||
|
||||
function _M:is_in_cache(ip)
|
||||
local kind, err = datastore:get("plugin_dnsbl_cache_" .. ip)
|
||||
if not kind then
|
||||
if err ~= "not found" then
|
||||
logger.log(ngx.ERR, "DNSBL", "Error while accessing cache : " .. err)
|
||||
end
|
||||
return false, err
|
||||
end
|
||||
return kind, "success"
|
||||
end
|
||||
|
||||
function _M:add_to_cache(ip, kind)
|
||||
local ok, err = datastore:set("plugin_dnsbl_cache_" .. ip, kind, 3600)
|
||||
if not ok then
|
||||
logger.log(ngx.ERR, "DNSBL", "Error while adding ip to cache : " .. err)
|
||||
return false, err
|
||||
end
|
||||
return true, "success"
|
||||
end
|
||||
|
||||
return _M
|
||||
27
core/dnsbl/plugin.json
Normal file
27
core/dnsbl/plugin.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"id": "dnsbl",
|
||||
"order": 2,
|
||||
"name": "DNSBL",
|
||||
"description": "Deny access based on external DNSBL servers.",
|
||||
"version": "0.1",
|
||||
"settings": {
|
||||
"USE_DNSBL": {
|
||||
"context": "multisite",
|
||||
"default": "yes",
|
||||
"help": "Activate DNSBL feature.",
|
||||
"id": "use-dnsbl",
|
||||
"label": "Activate DNSBL",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"DNSBL_LIST": {
|
||||
"context": "global",
|
||||
"default": "bl.blocklist.de problems.dnsbl.sorbs.net sbl.spamhaus.org xbl.spamhaus.org",
|
||||
"help": "List of DNSBL servers.",
|
||||
"id": "dnsbl-list",
|
||||
"label": "DNSBL list",
|
||||
"regex": "^.*$",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user