在/usr/share/rspamd/rules/regexp/headers.lua 里面通过下面lua代码实现具体的domain或者user列表可以通过mysql 或者文件读取出来,这暂时省略,仅
在/usr/share/rspamd/rules/regexp/headers.lua 里面通过下面lua代码实现
具体的domain或者user列表可以通过mysql 或者文件读取出来,这暂时省略,仅作记录
rspamd_config.USER_WHITELIST = { score = -200, description = 'in user whitelist', group = 'header', callback = function(task) local addr = task:get_from(1)[1]['addr'] local domain = task:get_from(1)[1]['domain'] if (domain == "oschina.net") then return true end return false end}
刚开始使用的时候可以用
local rspamd_logger = require "rspamd_logger"rspamd_logger.infox(task, "check for domain ".. addr .." ".. domain)
把相应的参数结果打印在日志里面方便调试
经过调试,可以以模块的方式比较方便,先通过获取收件人地址,在mysql中取得收件人maildir,得到黑白名单文件路径,再进行判断,后期可以改成使用redis缓存maildir,效率应该会好很多
white_black.lua 源码
-- 将str以split_char进行分割function string_split(str, split_char) local sub_str_tab = {} while (true) do local pos = string.find(str, split_char) if (not pos) then sub_str_tab[#sub_str_tab + 1] = str break end local sub_str = string.sub(str, 1, pos - 1) sub_str_tab[#sub_str_tab + 1] = sub_str str = string.sub(str, pos + 1, #str) end return sub_str_tab;end-- 判断str是否在array中function in_list(str, array) for i=1,table.getn(array) do if (str == array[i]) then return true end endendfunction w_b_list(str,to_addr) luasql = require "luasql.mysql" env = luasql.mysql() conn = env:connect("test","root","password") sql = "select dir from mailbox where CONCAT(name,'@',domain) = '" .. to_addr .. "'" result,errorstr = conn:execute(sql); row = result:fetch({},"a") while row do dir = string.format("%s",row.dir) row = result:fetch({},"a") end conn:close() env:close() list_arr = {} if(str == "whitelist") then file = dir.."/.whitelist" elseif(str == "blacklist") then file= dir.."/.blacklist" end handle,err = io.open(file,"r") if(handle) then list_arr = string_split(handle:read("*a"),"/n") return list_arr end handle:close()end
header.lua 里面调用
require "white_black"rspamd_config.USER_WHITELIST = { score = -1000, description = 'in user whitelist', group = 'header', callback = function(task) local from_addr = task:get_from(1)[1]['addr'] local from_domain = task:get_from(1)[1]['domain'] local to_addr = task:get_recipients(1)[1]['addr'] local list = w_b_list("whitelist",to_addr) if in_list(from_addr,list) or in_list(from_domain,list) then task:set_pre_result('no action', 'in user whitelist') return true end return false end}rspamd_config.USER_BLACKLIST = { score = 1000, description = 'in user blacklist', group = 'header', callback = function(task) local from_addr = task:get_from(1)[1]['addr'] local from_domain = task:get_from(1)[1]['domain'] local to_addr = task:get_recipients(1)[1]['addr'] local list = w_b_list("blacklist",to_addr) if in_list(from_addr,list) or in_list(from_domain,list) then task:set_pre_result('reject', 'in user blacklist') --task:set_metric_action('default', 'reject') return true end return false end}
黑名单同理。这里面白名单格式为user@domain@domain
判断 @domain 在白名单里面即判断为命中,也可以自己调整