]> source.dussan.org Git - rspamd.git/commitdiff
[Rework] Dmarc: Rework reports keys structure
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 30 Jul 2021 15:21:33 +0000 (16:21 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 30 Jul 2021 15:21:33 +0000 (16:21 +0100)
src/plugins/lua/dmarc.lua

index a46c6d7ab38d5d5ad591b0959ecf36930465b49c..d9e44f45575d35837e6c736985e104e8eca2327d 100644 (file)
@@ -57,6 +57,7 @@ local settings = {
   no_sampling_domains = nil,
   no_reporting_domains = nil,
   reporting = {
+    report_local_controller = false, -- Store reports for local/controller scans (for testing only)
     redis_keys = {
       index_prefix = 'dmarc_idx',
       report_prefix = 'dmarc_rpt',
@@ -135,19 +136,30 @@ end
 -- Returns a key used to be inserted into dmarc report sample
 local function dmarc_report(task, spf_ok, dkim_ok, disposition,
     sampled_out, hfromdom, spfdom, dres, spf_result)
+  local rspamd_lua_utils = require "lua_util"
+
   local ip = task:get_from_ip()
   if ip and not ip:is_valid() then
+    rspamd_logger.infox(task, 'cannot store dmarc report for %s: no valid source IP',
+        hfromdom)
     return nil
   end
-  local rspamd_lua_utils = require "lua_util"
-  if rspamd_lua_utils.is_rspamc_or_controller(task) then return end
+
+  ip = ip:to_string()
+
+  if rspamd_lua_utils.is_rspamc_or_controller(task) and not settings.reporting.report_local_controller then
+    rspamd_logger.infox(task, 'cannot store dmarc report for %s from IP %s: has come from controller/rspamc',
+        hfromdom, ip)
+    return
+  end
+
   local dkim_pass = table.concat(dres.pass or E, '|')
   local dkim_fail = table.concat(dres.fail or E, '|')
   local dkim_temperror = table.concat(dres.temperror or E, '|')
   local dkim_permerror = table.concat(dres.permerror or E, '|')
   local disposition_to_return = (disposition == "softfail") and "none" or disposition
   local res = table.concat({
-    ip:to_string(), spf_ok, dkim_ok,
+    ip, spf_ok, dkim_ok,
     disposition_to_return, (sampled_out and 'sampled_out' or ''), hfromdom,
     dkim_pass, dkim_fail, dkim_temperror, dkim_permerror, spfdom, spf_result}, ',')
 
@@ -449,18 +461,18 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
     if settings.no_reporting_domains then
       if settings.no_reporting_domains:get_key(policy.domain) or
           settings.no_reporting_domains:get_key(rspamd_util.get_tld(policy.domain)) then
-        rspamd_logger.infox(task, 'DMARC reporting suppressed for %1', policy.domain)
+        rspamd_logger.infox(task, 'DMARC reporting suppressed for %s', policy.domain)
         return
       end
     end
 
     local function dmarc_report_cb(err)
       if not err then
-        rspamd_logger.infox(task, '<%1> dmarc report saved for %2',
-            task:get_message_id(), hdrfromdom)
+        rspamd_logger.infox(task, 'dmarc report saved for %s (rua = %s)',
+            hdrfromdom, policy.rua)
       else
-        rspamd_logger.errx(task, '<%1> dmarc report is not saved for %2: %3',
-            task:get_message_id(), hdrfromdom, err)
+        rspamd_logger.errx(task, 'dmarc report is not saved for %s: %s',
+            hdrfromdom, err)
       end
     end
 
@@ -486,8 +498,10 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
     -- Prepare and send redis report element
     local period = os.date('!%Y%m%d',
         task:get_date({format = 'connect', gmt = true}))
+
+    -- Dmarc domain key must include dmarc domain, rua and period
     local dmarc_domain_key = table.concat(
-        {settings.reporting.redis_keys.report_prefix, hdrfromdom, period},
+        {settings.reporting.redis_keys.report_prefix, hdrfromdom, policy.rua, period},
         settings.reporting.redis_keys.join_char)
     local report_data = dmarc_report(task,
         spf_ok and 'pass' or 'fail',
@@ -499,8 +513,9 @@ local function dmarc_validate_policy(task, policy, hdrfromdom, dmarc_esld)
         dkim_results,
         spf_result)
 
-    local idx_key = table.concat({settings.redis_keys.index_prefix, period},
-        settings.redis_keys.join_char)
+
+    local idx_key = table.concat({settings.reporting.redis_keys.index_prefix, period},
+        settings.reporting.redis_keys.join_char)
 
     if report_data then
       rspamd_redis.exec_redis_script(take_report_id,