diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-10-07 18:20:47 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-10-07 18:20:47 +0100 |
commit | 94226d58fbdfb8fdacefbfa3b0f84b9e48578e34 (patch) | |
tree | 93304521e2e2b32b6fb9db732a73c56ff7451fc2 /src/plugins | |
parent | e528ad8f4d8057f0373cfe9c402873a3c4783206 (diff) | |
download | rspamd-94226d58fbdfb8fdacefbfa3b0f84b9e48578e34.tar.gz rspamd-94226d58fbdfb8fdacefbfa3b0f84b9e48578e34.zip |
[Minor] Add redis backend
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/lua/reputation.lua | 96 |
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 |