]> source.dussan.org Git - rspamd.git/commitdiff
[Rework] Resolve rdns in a separate function
authorVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 6 Aug 2024 12:45:27 +0000 (13:45 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Tue, 6 Aug 2024 12:45:27 +0000 (13:45 +0100)
Historically, it was done in `once_received` module, however, that check must
be done early, even before settings (as they could rely on hostname).

Hence, it was discussed to move this code to a separate rule.

conf/modules.d/once_received.conf
conf/scores.d/headers_group.conf
conf/scores.d/hfilter_group.conf
rules/misc.lua
src/plugins/lua/once_received.lua

index ab074929596929ccc35a93fc92af4f4a3b1b8f03..6fcc35bb654c1c66b90d7c2efbde6a2110687017 100644 (file)
@@ -14,8 +14,7 @@
 
 once_received {
   good_host = "mail";
-  bad_host = "static";
-  bad_host = "dynamic";
+  bad_host = ["static", "dynamic"];
   symbol_strict = "ONCE_RECEIVED_STRICT";
   symbol = "ONCE_RECEIVED";
   symbol_mx = "DIRECT_TO_MX";
index 1c70ca588f963709c3db1d42f521898d79071f64..972c6872a50b44314410db53d74b64a550fda409 100644 (file)
@@ -50,14 +50,6 @@ symbols = {
         weight = 0.1;
         description = "One received header in a message";
     }
-    "RDNS_NONE" {
-        weight = 2.0;
-        description = "Cannot resolve reverse DNS for sender's IP";
-    }
-    "RDNS_DNSFAIL" {
-        weight = 0.0;
-        description = "PTR verification DNS error";
-    }
     "ONCE_RECEIVED_STRICT" {
         weight = 4.0;
         description = "One received header with 'bad' patterns inside";
index 09fcfcd8db31091ac04fa4121b65f6c0406e99d8..21cd11a60b55e176cb75bb6f1021205886b18fc5 100644 (file)
@@ -130,4 +130,12 @@ symbols = {
         weight = 2.5;
         description = "One line URL and text in body";
     }
+    "RDNS_NONE" {
+        weight = 2.0;
+        description = "Cannot resolve reverse DNS for sender's IP";
+    }
+    "RDNS_DNSFAIL" {
+        weight = 0.0;
+        description = "PTR verification DNS error";
+    }
 }
index faf4a8fb8ec2eecb5fdd848af2bad5a4f3c7dc27..cbe90e56159b4860626a6770c8bebd751838375d 100644 (file)
@@ -862,3 +862,58 @@ rspamd_config.COMPLETELY_EMPTY = {
   group = 'blankspam',
   score = 15
 }
+
+-- Check for the hostname if it was not set
+local rnds_check_id = rspamd_config:register_symbol {
+  name = 'RDNS_CHECK',
+  callback = function(task)
+    if not task:get_hostname() then
+      -- Try to resolve
+      local task_ip = task:get_ip()
+      if task_ip and task_ip:is_valid() then
+        local rspamd_logger = require "rspamd_logger"
+        local function rdns_dns_cb(_, to_resolve, results, err)
+          if err and (err ~= 'requested record is not found' and err ~= 'no records with this name') then
+            rspamd_logger.errx(task, 'error looking up %s: %s', to_resolve, err)
+            task:insert_result('RDNS_DNSFAIL', 1.0)
+          end
+
+          if not results then
+            task:insert_result('RDNS_NONE', 1.0)
+          else
+            rspamd_logger.infox(task, 'source hostname has not been passed to Rspamd from MTA, ' ..
+                'but we could resolve source IP address PTR %s as "%s"',
+                to_resolve, results[1])
+            task:set_hostname(results[1])
+          end
+        end
+        task:get_resolver():resolve_ptr({ task = task,
+                                          name = task_ip:to_string(),
+                                          callback = rdns_dns_cb,
+                                          forced = true
+        })
+      end
+    end
+  end,
+  type = 'prefilter',
+  priority = lua_util.symbols_priorities.top,
+  description = 'Check if hostname has been resolved by MTA',
+}
+
+rspamd_config:register_symbol {
+  type = 'virtual',
+  name = 'RDNS_DNSFAIL',
+  score = 0.0,
+  description = 'DNS failure resolving RDNS',
+  group = 'hfilter',
+  parent = rnds_check_id,
+
+}
+rspamd_config:register_symbol {
+  type = 'virtual',
+  name = 'RDNS_NONE',
+  score = 2.0,
+  description = 'DNS failure resolving RDNS',
+  group = 'hfilter',
+  parent = rnds_check_id,
+}
\ No newline at end of file
index 2a5552ab918d9c86380ea0c80b856c762d7da9ef..5c5ff7986d70fdda74d03de32c2e9b2691e18f3f 100644 (file)
@@ -19,10 +19,7 @@ if confighelp then
 end
 
 -- 0 or 1 received: = spam
-
 local symbol = 'ONCE_RECEIVED'
-local symbol_rdns = 'RDNS_NONE'
-local symbol_rdns_dnsfail = 'RDNS_DNSFAIL'
 local symbol_mx = 'DIRECT_TO_MX'
 -- Symbol for strict checks
 local symbol_strict = nil
@@ -47,54 +44,6 @@ local function check_quantity_received (task)
     return not h['flags']['artificial']
   end, recvh))
 
-  local function recv_dns_cb(_, to_resolve, results, err)
-    if err and (err ~= 'requested record is not found' and err ~= 'no records with this name') then
-      rspamd_logger.errx(task, 'error looking up %s: %s', to_resolve, err)
-      task:insert_result(symbol_rdns_dnsfail, 1.0)
-    end
-
-    if not results then
-      if nreceived <= 1 then
-        task:insert_result(symbol, 1)
-        -- Avoid strict symbol inserting as the remaining symbols have already
-        -- quote a significant weight, so a message could be rejected by just
-        -- this property.
-        --task:insert_result(symbol_strict, 1)
-        -- Check for MUAs
-        local ua = task:get_header('User-Agent')
-        local xm = task:get_header('X-Mailer')
-        if (ua or xm) then
-          task:insert_result(symbol_mx, 1, (ua or xm))
-        end
-      end
-      task:insert_result(symbol_rdns, 1)
-    else
-      rspamd_logger.infox(task, 'source hostname has not been passed to Rspamd from MTA, ' ..
-          'but we could resolve source IP address PTR %s as "%s"',
-          to_resolve, results[1])
-      task:set_hostname(results[1])
-
-      if good_hosts then
-        for _, gh in ipairs(good_hosts) do
-          if string.find(results[1], gh) then
-            return
-          end
-        end
-      end
-
-      if nreceived <= 1 then
-        task:insert_result(symbol, 1)
-        for _, h in ipairs(bad_hosts) do
-          if string.find(results[1], h) then
-
-            task:insert_result(symbol_strict, 1, h)
-            return
-          end
-        end
-      end
-    end
-  end
-
   local task_ip = task:get_ip()
 
   if ((not check_authed and task:get_user()) or
@@ -110,13 +59,39 @@ local function check_quantity_received (task)
 
   local hn = task:get_hostname()
   -- Here we don't care about received
-  if (not hn) and task_ip and task_ip:is_valid() then
-    task:get_resolver():resolve_ptr({ task = task,
-                                      name = task_ip:to_string(),
-                                      callback = recv_dns_cb,
-                                      forced = true
-    })
+  if not hn then
+    if nreceived <= 1 then
+      task:insert_result(symbol, 1)
+      -- Avoid strict symbol inserting as the remaining symbols have already
+      -- quote a significant weight, so a message could be rejected by just
+      -- this property.
+      --task:insert_result(symbol_strict, 1)
+      -- Check for MUAs
+      local ua = task:get_header('User-Agent')
+      local xm = task:get_header('X-Mailer')
+      if (ua or xm) then
+        task:insert_result(symbol_mx, 1, (ua or xm))
+      end
+    end
     return
+  else
+    if good_hosts then
+      for _, gh in ipairs(good_hosts) do
+        if string.find(hn, gh) then
+          return
+        end
+      end
+    end
+
+    if nreceived <= 1 then
+      task:insert_result(symbol, 1)
+      for _, h in ipairs(bad_hosts) do
+        if string.find(hn, h) then
+          task:insert_result(symbol_strict, 1, h)
+          break
+        end
+      end
+    end
   end
 
   if nreceived <= 1 then
@@ -181,10 +156,6 @@ if opts then
     for n, v in pairs(opts) do
       if n == 'symbol_strict' then
         symbol_strict = v
-      elseif n == 'symbol_rdns' then
-        symbol_rdns = v
-      elseif n == 'symbol_rdns_dnsfail' then
-        symbol_rdns_dnsfail = v
       elseif n == 'bad_host' then
         if type(v) == 'string' then
           bad_hosts[1] = v
@@ -206,16 +177,6 @@ if opts then
       end
     end
 
-    rspamd_config:register_symbol({
-      name = symbol_rdns,
-      type = 'virtual',
-      parent = id
-    })
-    rspamd_config:register_symbol({
-      name = symbol_rdns_dnsfail,
-      type = 'virtual',
-      parent = id
-    })
     rspamd_config:register_symbol({
       name = symbol_strict,
       type = 'virtual',