summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-10-07 18:20:47 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-10-07 18:20:47 +0100
commit94226d58fbdfb8fdacefbfa3b0f84b9e48578e34 (patch)
tree93304521e2e2b32b6fb9db732a73c56ff7451fc2 /src/plugins
parente528ad8f4d8057f0373cfe9c402873a3c4783206 (diff)
downloadrspamd-94226d58fbdfb8fdacefbfa3b0f84b9e48578e34.tar.gz
rspamd-94226d58fbdfb8fdacefbfa3b0f84b9e48578e34.zip
[Minor] Add redis backend
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/lua/reputation.lua96
1 files changed, 87 insertions, 9 deletions
diff --git a/src/plugins/lua/reputation.lua b/src/plugins/lua/reputation.lua
index e0ee5f268..d19d0da94 100644
--- a/src/plugins/lua/reputation.lua
+++ b/src/plugins/lua/reputation.lua
@@ -38,11 +38,15 @@ local default_expiry = 864000 -- 10 day by default
-- Selectors are used to extract reputation tokens
local ip_selector = {
config = {
- actions = { -- how each action is treated in scoring
- ['reject'] = 1.0,
- ['add header'] = 0.25,
- ['rewrite subject'] = 0.25,
- ['no action'] = 1.0
+ -- keys map between actions and hash elements in bucket,
+ -- h is for ham,
+ -- s is for spam,
+ -- p is for probable spam
+ keys_map = {
+ ['reject'] = 's',
+ ['add header'] = 'p',
+ ['rewrite subject'] = 'p',
+ ['no action'] = 'h'
},
scores = { -- how each component is evaluated
['asn'] = 0.4,
@@ -51,7 +55,6 @@ local ip_selector = {
['ip'] = 1.0
},
symbol = 'IP_SCORE', -- symbol to be inserted
- hash = 'ip_score', -- hash table in redis used for storing scores
asn_suffix = 'a:', -- prefix for ASN hashes
country_suffix = 'c:', -- prefix for country hashes
ipnet_suffix = 'n:', -- prefix for ipnet hashes
@@ -172,10 +175,84 @@ local function reputation_dns_get_token(task, rule, token, continuation_cb)
})
end
-local function reputation_redis_get_token(task, token, continuation_cb)
+local function reputation_redis_get_token(task, rule, token, continuation_cb)
+ local key = gen_token_key(token)
+
+ local function redis_get_cb(err, data)
+ if data then
+ if type(data) == 'table' then
+ local values = {}
+ for i=1,#data,2 do
+ local ndata = tonumber(data[i + 1])
+ if ndata then
+ values[data[i]] = ndata
+ end
+ end
+ continuation_cb(nil, key, values)
+ else
+ rspamd_logger.errx(task, 'invalid type while getting reputation keys %s: %s',
+ key, type(data))
+ continuation_cb("invalid type", key, nil)
+ end
+
+ elseif err then
+ rspamd_logger.errx(task, 'got error while getting reputation keys %s: %s',
+ key, err)
+ continuation_cb(err, key, nil)
+ else
+ continuation_cb("unknown error", key, nil)
+ end
+ end
+
+ local ret = rspamd_redis_make_request(task,
+ redis_params, -- connect params
+ key, -- hash key
+ false, -- is write
+ redis_get_cb, --callback
+ 'HGETALL', -- command
+ {key} -- arguments
+ )
+ if not ret then
+ rspamd_logger.errx(task, 'cannot make redis request to check results')
+ end
end
-local function reputation_redis_set_token(task, token, values, continuation_cb)
+local function reputation_redis_set_token(task, rule, token, values, continuation_cb)
+ local key = gen_token_key(token)
+
+ local ret,conn,upstream
+
+ local function redis_set_cb(err, data)
+ if err then
+ rspamd_logger.errx(task, 'got error while setting reputation keys %s: %s',
+ key, err)
+ continuation_cb(err, key)
+ else
+ continuation_cb(nil, key)
+ end
+ end
+
+ -- We start from expiry update
+ ret,conn,upstream = rspamd_redis_make_request(task,
+ redis_params, -- connect params
+ nil, -- hash key
+ true, -- is write
+ redis_set_cb, --callback
+ 'EXPIRE', -- command
+ {key, tostring(rule.backend.config.expiry)} -- arguments
+ )
+ -- Update greylisting record expire
+ if ret then
+ -- Here, we increment all hash keys that are listed in values
+ -- E.g. {'s': 1.0} or {'h': -1.0}, floating point allows better flexibility
+ fun.each(function(k, v)
+ conn:add_cmd('HINCRBYFLOAT', {key, tostring(k), tostring(v)})
+ end, values)
+ -- Add last modification time (might be not very consistent between updates)
+ conn:add_cmd('HSET', {key, 'last', tostring(rspamd_util:get_calendar_ticks())})
+ else
+ rspamd_logger.errx(task, 'got error while connecting to redis')
+ end
end
--[[ Backends are responsible for getting reputation tokens
@@ -195,6 +272,7 @@ local backends = {
},
dns = {
config = {
+ -- list = rep.example.com
},
get_token = reputation_dns_get_token,
-- No set token for DNS
@@ -335,7 +413,7 @@ local function parse_rule(name, tbl)
end
redis_params = rspamd_parse_redis_server('reputation')
-local opts = rspamd_config:get_all_opt("fann_redis")
+local opts = rspamd_config:get_all_opt("reputation")
-- Initialization part
if not (opts and type(opts) == 'table') then