mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
add forward reverse DNS to whitelist, disable redis in cachestore when sockets are not enabled, fix typo in cachestore and improve dns/rdns caching
This commit is contained in:
parent
8a8dd6fb7a
commit
b5aaf62662
4 changed files with 63 additions and 21 deletions
|
|
@ -1,5 +1,6 @@
|
|||
local mlcache = require "resty.mlcache"
|
||||
local logger = require "bunkerweb.logger"
|
||||
local utils = require "bunkerweb.utils"
|
||||
local class = require "middleclass"
|
||||
local cachestore = class("cachestore")
|
||||
|
||||
|
|
@ -42,7 +43,7 @@ end
|
|||
|
||||
function cachestore:initialize(use_redis)
|
||||
self.cache = cache
|
||||
self.use_redis = use_redis or false
|
||||
self.use_redis = (use_redis and utils.is_cosocket_available()) or false
|
||||
self.logger = module_logger
|
||||
end
|
||||
|
||||
|
|
@ -101,7 +102,7 @@ end
|
|||
|
||||
function cachestore:set(key, value, ex)
|
||||
if self.use_redis then
|
||||
local ok, err = self.set_redis(key, value, ex)
|
||||
local ok, err = self:set_redis(key, value, ex)
|
||||
if not ok then
|
||||
self.logger:log(ngx.ERR, err)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ utils.get_resolvers = function()
|
|||
return resolvers
|
||||
end
|
||||
|
||||
utils.get_rdns = function(ip)
|
||||
utils.get_rdns = function(ip)
|
||||
-- Check cache
|
||||
local cachestore = utils.new_cachestore()
|
||||
local ok, value = cachestore:get("rdns_" .. ip)
|
||||
|
|
@ -347,20 +347,24 @@ utils.get_rdns = function(ip)
|
|||
if not rdns then
|
||||
return false, err
|
||||
end
|
||||
-- Our results
|
||||
local ptrs = {}
|
||||
local ret_err = "success"
|
||||
-- Do rDNS query
|
||||
local answers, err = rdns:reverse_query(ip)
|
||||
if not answers then
|
||||
return false, err
|
||||
end
|
||||
local ret_err = "success"
|
||||
if answers.errcode then
|
||||
ret_err = answers.errstr
|
||||
end
|
||||
-- Extract all PTR
|
||||
local ptrs = {}
|
||||
for i, answer in ipairs(answers) do
|
||||
if answer.ptrdname then
|
||||
table.insert(ptrs, answer.ptrdname)
|
||||
logger:log(ngx.ERR, "error while doing reverse DNS query for " .. ip .. " : " .. err)
|
||||
ret_err = err
|
||||
else
|
||||
if answers.errcode then
|
||||
ret_err = answers.errstr
|
||||
end
|
||||
-- Extract all PTR
|
||||
for i, answer in ipairs(answers) do
|
||||
if answer.ptrdname then
|
||||
table.insert(ptrs, answer.ptrdname)
|
||||
logger:log(ngx.ERR, answer.ptrdname)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Save to cache
|
||||
|
|
@ -371,7 +375,7 @@ utils.get_rdns = function(ip)
|
|||
return ptrs, ret_err
|
||||
end
|
||||
|
||||
utils.get_ips = function(fqdn, ipv6)
|
||||
utils.get_ips = function(fqdn, ipv6)
|
||||
-- Check cache
|
||||
local cachestore = utils.new_cachestore()
|
||||
local ok, value = cachestore:get("dns_" .. fqdn)
|
||||
|
|
@ -425,8 +429,8 @@ utils.get_ips = function(fqdn, ipv6)
|
|||
table.insert(res_answers, answers)
|
||||
end
|
||||
end
|
||||
if #res_errors == #qtypes then
|
||||
return false, cjson.encode(res_errors)
|
||||
for qtype, error in pairs(res_errors) do
|
||||
logger:log(ngx.ERR, "error while doing " .. qtype .. " DNS query for " .. fqdn .. " : " .. error)
|
||||
end
|
||||
-- Extract all IPs
|
||||
local ips = {}
|
||||
|
|
@ -653,4 +657,19 @@ utils.get_phases = function()
|
|||
}
|
||||
end
|
||||
|
||||
utils.is_cosocket_available = function()
|
||||
local phases = {
|
||||
"timer",
|
||||
"access",
|
||||
"preread"
|
||||
}
|
||||
local current_phase = ngx.get_phase()
|
||||
for i, phase in ipairs(phases) do
|
||||
if current_phase == phase then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return utils
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ local redis = class("redis", plugin)
|
|||
function redis:initialize()
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "redis")
|
||||
self.clusterstore = clusterstore:new()
|
||||
end
|
||||
|
||||
function redis:init_worker()
|
||||
|
|
@ -17,13 +18,13 @@ function redis:init_worker()
|
|||
return self:ret(true, "init_worker not needed")
|
||||
end
|
||||
-- Check redis connection
|
||||
local ok, err = clusterstore:connect()
|
||||
local ok, err = self.clusterstore:connect()
|
||||
if not ok then
|
||||
return self:ret(false, "redis connect error : " .. err)
|
||||
end
|
||||
-- Send ping
|
||||
local ok, err = clusterstore:call("ping")
|
||||
clusterstore:close()
|
||||
local ok, err = self.clusterstore:call("ping")
|
||||
self.clusterstore:close()
|
||||
if err then
|
||||
return self:ret(false, "error while sending ping command to redis server : " .. err)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -256,12 +256,33 @@ function whitelist:is_whitelisted_ip()
|
|||
local rdns_list, err = utils.get_rdns(ngx.ctx.bw.remote_addr)
|
||||
-- Check if rDNS is in whitelist
|
||||
if rdns_list then
|
||||
local forward_check = nil
|
||||
local rdns_suffix = nil
|
||||
for i, rdns in ipairs(rdns_list) do
|
||||
for j, suffix in ipairs(self.lists["RDNS"]) do
|
||||
if rdns:sub(- #suffix) == suffix then
|
||||
return true, "rDNS " .. suffix
|
||||
forward_check = rdns
|
||||
rdns_suffix = suffix
|
||||
break
|
||||
end
|
||||
end
|
||||
if forward_check then
|
||||
break
|
||||
end
|
||||
end
|
||||
if forward_check then
|
||||
local forward_ok = false
|
||||
local ip_list, err = utils.get_ips(forward_check)
|
||||
if ip_list then
|
||||
for i, ip in ipairs(ip_list) do
|
||||
if ip == ngx.ctx.bw.remote_addr then
|
||||
return true, "rDNS " .. rdns_suffix
|
||||
end
|
||||
end
|
||||
self.logger:log(ngx.WARN, "IP " .. ngx.ctx.bw.remote_addr .. " may spoof reverse DNS " .. forward_check)
|
||||
else
|
||||
self.logger:log(ngx.ERR, "error while getting rdns (forward check) : " .. err)
|
||||
end
|
||||
end
|
||||
else
|
||||
self.logger:log(ngx.ERR, "error while getting rdns : " .. err)
|
||||
|
|
|
|||
Loading…
Reference in a new issue