aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/modules.conf1
-rw-r--r--doc/markdown/modules/rbl.md6
-rw-r--r--src/plugins/lua/rbl.lua326
3 files changed, 207 insertions, 126 deletions
diff --git a/conf/modules.conf b/conf/modules.conf
index 719b86793..a72eb1818 100644
--- a/conf/modules.conf
+++ b/conf/modules.conf
@@ -86,6 +86,7 @@ rbl {
default_from = true;
default_received = false;
+ default_user = false;
rbls {
diff --git a/doc/markdown/modules/rbl.md b/doc/markdown/modules/rbl.md
index 84bb91478..3bcbf839b 100644
--- a/doc/markdown/modules/rbl.md
+++ b/doc/markdown/modules/rbl.md
@@ -19,7 +19,7 @@ rbl {
The default settings define the ways in which the RBLs are used unless overridden in an RBL-specific subsection.
-Defaults may be set for the following parameters (default values used if these are not set are shown in brackets):
+Defaults may be set for the following parameters (default values used if these are not set are shown in brackets - note that these may be redefined in the default config):
- default_ipv4 (true)
@@ -49,6 +49,10 @@ Use this RBL to test parameters sent for HELO/EHLO at SMTP time.
If set to false, do not yield a result unless the response received from the RBL is defined in its related returncodes {} subsection, else return the default symbol for the RBL.
+- deault_user (true)
+
+If set to false, do not use this RBL if the message sender is authenticated.
+
RBL-specific subsection is structured as follows:
~~~nginx
diff --git a/src/plugins/lua/rbl.lua b/src/plugins/lua/rbl.lua
index 5b6165d80..9258c1e86 100644
--- a/src/plugins/lua/rbl.lua
+++ b/src/plugins/lua/rbl.lua
@@ -3,159 +3,235 @@ local rbls = {}
local rspamd_logger = require "rspamd_logger"
local function ip_to_rbl(ip, rbl)
- return table.concat(ip:inversed_str_octets(), ".") .. '.' .. rbl
+ return table.concat(ip:inversed_str_octets(), ".") .. '.' .. rbl
end
local function rbl_cb (task)
- local function rbl_dns_cb(resolver, to_resolve, results, err, key)
- if results then
- local thisrbl = nil
- for k,r in pairs(rbls) do
- if k == key then
- thisrbl = r
- break
- end
- end
- if thisrbl ~= nil then
- if thisrbl['returncodes'] == nil then
- if thisrbl['symbol'] ~= nil then
- task:insert_result(thisrbl['symbol'], 1)
- end
- else
- for _,result in pairs(results) do
- local ipstr = result:to_string()
- local foundrc = false
- for s,i in pairs(thisrbl['returncodes']) do
- if type(i) == 'string' then
- if string.find(ipstr, "^" .. i .. "$") then
- foundrc = true
- task:insert_result(s, 1)
- break
- end
- elseif type(i) == 'table' then
- for _,v in pairs(i) do
- if string.find(ipstr, "^" .. v .. "$") then
- foundrc = true
- task:insert_result(s, 1)
- break
- end
- end
- end
- end
- if not foundrc then
- if thisrbl['unknown'] and thisrbl['symbol'] then
- task:insert_result(thisrbl['symbol'], 1)
- else
- rspamd_logger.err('RBL ' .. thisrbl['rbl'] .. ' returned unknown result ' .. ipstr)
- end
- end
- end
- end
- end
- end
- task:inc_dns_req()
- end
+ local function rbl_dns_cb(resolver, to_resolve, results, err, key)
+ if results then
+ local thisrbl = nil
+ for k,r in pairs(rbls) do
+ if k == key then
+ thisrbl = r
+ break
+ end
+ end
+ if thisrbl ~= nil then
+ if thisrbl['returncodes'] == nil then
+ if thisrbl['symbol'] ~= nil then
+ task:insert_result(thisrbl['symbol'], 1)
+ end
+ else
+ for _,result in pairs(results) do
+ local ipstr = result:to_string()
+ local foundrc = false
+ for s,i in pairs(thisrbl['returncodes']) do
+ if type(i) == 'string' then
+ if string.find(ipstr, "^" .. i .. "$") then
+ foundrc = true
+ task:insert_result(s, 1)
+ break
+ end
+ elseif type(i) == 'table' then
+ for _,v in pairs(i) do
+ if string.find(ipstr, "^" .. v .. "$") then
+ foundrc = true
+ task:insert_result(s, 1)
+ break
+ end
+ end
+ end
+ end
+ if not foundrc then
+ if thisrbl['unknown'] and thisrbl['symbol'] then
+ task:insert_result(thisrbl['symbol'], 1)
+ else
+ rspamd_logger.err('RBL ' .. thisrbl['rbl'] ..
+ ' returned unknown result ' .. ipstr)
+ end
+ end
+ end
+ end
+ end
+ end
+ task:inc_dns_req()
+ end
- local helo = task:get_helo()
- if helo and string.sub(helo,1,1) ~= '[' then
- for k,rbl in pairs(rbls) do
- if rbl['helo'] then
- task:get_resolver():resolve_a(task:get_session(), task:get_mempool(), helo .. '.' .. rbl['rbl'], rbl_dns_cb, k)
- end
- end
- end
- local sender_dns = task:get_hostname()
- if sender_dns ~= nil and sender_dns ~= 'unknown' then
- for k,rbl in pairs(rbls) do
- if rbl['rdns'] then
- task:get_resolver():resolve_a(task:get_session(), task:get_mempool(), sender_dns .. '.' .. rbl['rbl'], rbl_dns_cb, k)
- end
- end
- end
- local rip = task:get_from_ip()
- if rip and (rip:to_string() ~= '0.0.0.0') then
- for k,rbl in pairs(rbls) do
- if (rip:get_version() == 6 and rbl['ipv6'] and rbl['from']) or
- (rip:get_version() == 4 and rbl['ipv4'] and rbl['from']) then
- task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
- ip_to_rbl(rip, rbl['rbl']), rbl_dns_cb, k)
- end
- end
- end
- local recvh = task:get_received_headers()
- for _,rh in ipairs(recvh) do
- if rh['real_ip'] and rh['real_ip']:to_string() ~= '0.0.0.0' then
- for k,rbl in pairs(rbls) do
- if (rh['real_ip']:get_version() == 6 and rbl['ipv6'] and rbl['received']) or
- (rh['real_ip']:get_version() == 4 and rbl['ipv4'] and rbl['received']) then
- task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
- ip_to_rbl(rh['real_ip'], rbl['rbl']), rbl_dns_cb, k)
- end
- end
- end
- end
+ local havegot = {}
+ local notgot = {}
+ local function check_user()
+ if not havegot['user'] and not notgot['user'] then
+ havegot['user'] = task:get_user()
+ if havegot['user'] == nil then
+ notgot['user'] = true
+ end
+ end
+ if havegot['user'] ~= nil then
+ return true
+ end
+ return false
+ end
+
+ for k,rbl in pairs(rbls) do
+
+ if rbl['helo'] then
+ (function()
+ if notgot['helo'] then
+ return
+ end
+ if not havegot['helo'] then
+ havegot['helo'] = task:get_helo()
+ if havegot['helo'] == nil or string.sub(havegot['helo'],1,1) == '[' then
+ notgot['helo'] = true
+ return
+ end
+ end
+ if rbl['user'] == false and check_user() == true then
+ return
+ end
+ task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+ havegot['helo'] .. '.' .. rbl['rbl'], rbl_dns_cb, k)
+ end)()
+ end
+
+ if rbl['rdns'] then
+ (function()
+ if notgot['rdns'] then
+ return
+ end
+ if not havegot['rdns'] then
+ havegot['rdns'] = task:get_hostname()
+ if havegot['rdns'] == nil or havegot['rdns'] == 'unknown' then
+ notgot['rdns'] = true
+ return
+ end
+ end
+ if rbl['user'] == false and check_user() == true then
+ return
+ end
+ task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+ havegot['rdns'] .. '.' .. rbl['rbl'], rbl_dns_cb, k)
+ end)()
+ end
+
+ if rbl['from'] then
+ (function()
+ if notgot['from'] then
+ return
+ end
+ if not havegot['from'] then
+ havegot['from'] = task:get_from_ip()
+ if havegot['from'] == nil then
+ notgot['from'] = true
+ return
+ end
+ end
+ if (havegot['from']:get_version() == 6 and rbl['ipv6']) or
+ (havegot['from']:get_version() == 4 and rbl['ipv4']) then
+ if rbl['user'] == false and check_user() == true then
+ return
+ end
+ task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+ ip_to_rbl(havegot['from'], rbl['rbl']), rbl_dns_cb, k)
+ end
+ end)()
+ end
+
+ if rbl['received'] then
+ (function()
+ if notgot['received'] then
+ return
+ end
+ if not havegot['received'] then
+ havegot['received'] = task:get_received_headers()
+ if havegot['received'] == nil then
+ notgot['received'] = true
+ return
+ end
+ end
+ if rbl['user'] == false and check_user() == true then
+ return
+ end
+ for _,rh in ipairs(havegot['received']) do
+ if rh['real_ip'] and rh['real_ip']:to_string() ~= '0.0.0.0' then
+ for k,rbl in pairs(rbls) do
+ if (rh['real_ip']:get_version() == 6 and rbl['ipv6']) or
+ (rh['real_ip']:get_version() == 4 and rbl['ipv4']) then
+ task:get_resolver():resolve_a(task:get_session(), task:get_mempool(),
+ ip_to_rbl(rh['real_ip'], rbl['rbl']), rbl_dns_cb, k)
+ end
+ end
+ end
+ end
+ end)()
+ end
+ end
end
-- Registration
if type(rspamd_config.get_api_version) ~= 'nil' then
- if rspamd_config:get_api_version() >= 1 then
- rspamd_config:register_module_option('rbl', 'rbls', 'map')
- rspamd_config:register_module_option('rbl', 'default_ipv4', 'string')
- rspamd_config:register_module_option('rbl', 'default_ipv6', 'string')
- rspamd_config:register_module_option('rbl', 'default_received', 'string')
- rspamd_config:register_module_option('rbl', 'default_from', 'string')
- rspamd_config:register_module_option('rbl', 'default_rdns', 'string')
- rspamd_config:register_module_option('rbl', 'default_helo', 'string')
- rspamd_config:register_module_option('rbl', 'default_unknown', 'string')
- end
+ if rspamd_config:get_api_version() >= 1 then
+ rspamd_config:register_module_option('rbl', 'rbls', 'map')
+ rspamd_config:register_module_option('rbl', 'default_ipv4', 'string')
+ rspamd_config:register_module_option('rbl', 'default_ipv6', 'string')
+ rspamd_config:register_module_option('rbl', 'default_received', 'string')
+ rspamd_config:register_module_option('rbl', 'default_from', 'string')
+ rspamd_config:register_module_option('rbl', 'default_rdns', 'string')
+ rspamd_config:register_module_option('rbl', 'default_helo', 'string')
+ rspamd_config:register_module_option('rbl', 'default_unknown', 'string')
+ rspamd_config:register_module_option('rbl', 'default_user', 'string')
+ end
end
-- Configuration
local opts = rspamd_config:get_all_opt('rbl')
if not opts or type(opts) ~= 'table' then
- return
+ return
end
if(opts['default_ipv4'] == nil) then
- opts['default_ipv4'] = true
+ opts['default_ipv4'] = true
end
if(opts['default_ipv6'] == nil) then
- opts['default_ipv6'] = false
+ opts['default_ipv6'] = false
end
if(opts['default_received'] == nil) then
- opts['default_received'] = true
+ opts['default_received'] = true
end
if(opts['default_from'] == nil) then
- opts['default_from'] = false
+ opts['default_from'] = false
end
if(opts['default_unknown'] == nil) then
- opts['default_unknown'] = false
+ opts['default_unknown'] = false
end
if(opts['default_rdns'] == nil) then
- opts['default_rdns'] = false
+ opts['default_rdns'] = false
end
if(opts['default_helo'] == nil) then
- opts['default_helo'] = false
+ opts['default_helo'] = false
+end
+if(opts['default_user'] == nil) then
+ opts['default_user'] = true
end
for key,rbl in pairs(opts['rbls']) do
- local o = { "ipv4", "ipv6", "from", "received", "unknown", "rdns", "helo" }
- for i=1,table.maxn(o) do
- if(rbl[o[i]] == nil) then
- rbl[o[i]] = opts['default_' .. o[i]]
- end
- end
- if type(rbl['returncodes']) == 'table' then
- for s,_ in pairs(rbl['returncodes']) do
- if type(rspamd_config.get_api_version) ~= 'nil' then
- rspamd_config:register_virtual_symbol(s, 1)
- end
- end
- end
- if not rbl['symbol'] and type(rbl['returncodes']) ~= 'nil' and not rbl['unknown'] then
- rbl['symbol'] = key
- end
- if type(rspamd_config.get_api_version) ~= 'nil' and rbl['symbol'] then
- rspamd_config:register_virtual_symbol(rbl['symbol'], 1)
- end
- rbls[key] = rbl
+ local o = { "ipv4", "ipv6", "from", "received", "unknown", "rdns", "helo", "user" }
+ for i=1,table.maxn(o) do
+ if(rbl[o[i]] == nil) then
+ rbl[o[i]] = opts['default_' .. o[i]]
+ end
+ end
+ if type(rbl['returncodes']) == 'table' then
+ for s,_ in pairs(rbl['returncodes']) do
+ if type(rspamd_config.get_api_version) ~= 'nil' then
+ rspamd_config:register_virtual_symbol(s, 1)
+ end
+ end
+ end
+ if not rbl['symbol'] and type(rbl['returncodes']) ~= 'nil' and not rbl['unknown'] then
+ rbl['symbol'] = key
+ end
+ if type(rspamd_config.get_api_version) ~= 'nil' and rbl['symbol'] then
+ rspamd_config:register_virtual_symbol(rbl['symbol'], 1)
+ end
+ rbls[key] = rbl
end
rspamd_config:register_callback_symbol_priority('RBL', 1.0, 0, rbl_cb)