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:
florian 2023-05-19 21:23:50 +02:00
parent 8a8dd6fb7a
commit b5aaf62662
No known key found for this signature in database
GPG key ID: 3D80806F12602A7C
4 changed files with 63 additions and 21 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)