在/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
end
end
function 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 在白名单里面即判断为命中,也可以自己调整