diff options
-rw-r--r-- | conf/mid.inc | 9 | ||||
-rw-r--r-- | conf/modules.d/mid.conf | 25 | ||||
-rw-r--r-- | src/plugins/lua/mid.lua | 112 |
3 files changed, 146 insertions, 0 deletions
diff --git a/conf/mid.inc b/conf/mid.inc new file mode 100644 index 000000000..6207819a4 --- /dev/null +++ b/conf/mid.inc @@ -0,0 +1,9 @@ +# Known invalid or missed Message-IDs +# 'domain' 'Message-ID regexp' + +aliexpress.com /^(?:(?:[0-9]{14}|[a-z]{4}UTT_[0-9]{5}_)[$])?[a-f0-9]{32}$/ +is-zakupki.com +mirtesen.ru +promo.wildberries.ru /^[A-F0-9]{8}(?:-[A-F0-9]{4}){2}-[0-9]{4}-[A-F0-9]{12}$/ +sberbank-ast.ru +wildberries.ru /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/ diff --git a/conf/modules.d/mid.conf b/conf/modules.d/mid.conf new file mode 100644 index 000000000..36639790a --- /dev/null +++ b/conf/modules.d/mid.conf @@ -0,0 +1,25 @@ +# Please don't modify this file as your changes might be overwritten with +# the next update. +# +# You can modify '$LOCAL_CONFDIR/rspamd.conf.local.override' to redefine +# parameters defined on the top level +# +# You can modify '$LOCAL_CONFDIR/rspamd.conf.local' to add +# parameters defined on the top level +# +# For specific modules or configuration you can also modify +# '$LOCAL_CONFDIR/local.d/file.conf' - to add your options or rewrite defaults +# '$LOCAL_CONFDIR/override.d/file.conf' - to override the defaults +# +# See https://rspamd.com/doc/tutorials/writing_rules.html for details + +mid = { + url = [ + "${CONFDIR}/mid.inc", + "$LOCAL_CONFDIR/local.d/mid.inc" + ]; + + .include(try=true,priority=5) "${DBDIR}/dynamic/mid.conf" + .include(try=true,priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/mid.conf" + .include(try=true,priority=10) "$LOCAL_CONFDIR/override.d/mid.conf" +} diff --git a/src/plugins/lua/mid.lua b/src/plugins/lua/mid.lua new file mode 100644 index 000000000..b449746f9 --- /dev/null +++ b/src/plugins/lua/mid.lua @@ -0,0 +1,112 @@ +--[[ +Copyright (c) 2016, Alexander Moisseev <moiseev@mezonplus.ru> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +]]-- + +--[[ +MID plugin - suppress INVALID_MSGID and MISSING_MID for messages originating +from listed valid DKIM domains with missed or known proprietary Message-IDs +]]-- + +local rspamd_logger = require "rspamd_logger" +local rspamd_regexp = require "rspamd_regexp" + +local settings = { + url = '', + symbol_known_mid = 'KNOWN_MID', + symbol_known_no_mid = 'KNOWN_NO_MID', + symbol_invalid_msgid = 'INVALID_MSGID', + symbol_missing_mid = 'MISSING_MID', + symbol_dkim_allow = 'R_DKIM_ALLOW', + csymbol_invalid_msgid_allowed = 'INVALID_MSGID_ALLOWED', + csymbol_missing_mid_allowed = 'MISSING_MID_ALLOWED', +} + +local maps = {} + +local function known_mid_cb(task) + local re = {} + local header = task:get_header('Message-Id') + local das = task:get_symbol(settings['symbol_dkim_allow']) + if das and das[1] and das[1]['options'] then + for _,dkim_domain in ipairs(das[1]['options']) do + for _,map in ipairs(maps) do + local v = map:get_key(dkim_domain) + if v then + if v == '' then + if not header then + task:insert_result(settings['symbol_known_no_mid'], 1, dkim_domain) + return + end + else + re[dkim_domain] = rspamd_regexp.create_cached(v) + if header then + if re[dkim_domain]:match(header) then + task:insert_result(settings['symbol_known_mid'], 1, dkim_domain) + return + end + end + end + end + end + end + end +end + +local opts = rspamd_config:get_all_opt('mid') +if opts then + for k,v in pairs(opts) do + settings[k] = v + end + + if settings['url'] and #settings['url'] > 0 then + local urls = {} + if type(settings['url']) == 'table' then + urls = settings['url'] + else + urls[1] = settings['url'] + end + for i,u in ipairs(urls) do + maps[i] = rspamd_config:add_map ({ + url = u, + type = 'map', + description = 'Message-IDs map' + }) + end + + local id = rspamd_config:register_symbol({ + name = 'KNOWN_MID_CALLBACK', + type = 'callback', + callback = known_mid_cb + }) + rspamd_config:register_symbol({ + name = settings['symbol_known_mid'], + parent = id, + type = 'virtual' + }) + rspamd_config:register_symbol({ + name = settings['symbol_known_no_mid'], + parent = id, + type = 'virtual' + }) + rspamd_config:add_composite(settings['csymbol_invalid_msgid_allowed'], + settings['symbol_known_mid'] .. ' & ' .. settings['symbol_invalid_msgid']) + rspamd_config:add_composite(settings['csymbol_missing_mid_allowed'], + settings['symbol_known_no_mid'] .. ' & ' .. settings['symbol_missing_mid']) + + rspamd_config:register_dependency(id, settings['symbol_dkim_allow']) + else + rspamd_logger.infox(rspamd_config, 'url is not specified, disabling module') + end +end |