Skip to main content

Integration - Rspamd

Rspamd is a fast, modular, and high-performance open-source spam filtering system designed to process and filter email messages in real-time. It provides spam filtering, email virus scanning, and various email security checks, such as DKIM, DMARC, SPF, and greylisting, to prevent spam and malicious emails from reaching users' inboxes. Follow the steps below to integrate Rspamd with Contextal Platform.

Integration Steps

1. Prepare Python virtual environment and install the contextal package:

# virtualenv /opt/python
# /opt/python/pip install contextal

2. Configure platform profile for _rspamd user using the ctx tool:

# su _rspamd
$ /opt/python/bin/ctx config create --set-default rspamd http://platform_local_address

3. Copy the following Lua rule into /etc/rspamd/rspamd.local.lua:

local rspamd_regexp = require "rspamd_regexp"

local ctx_scan_path = "/opt/python/bin/ctx-scan"
local re_action_clean = rspamd_regexp.create("/: Clean$/")
local re_action_infected = rspamd_regexp.create("/: Contextal-Action-(SPAM|QUARANTINE|BLOCK): /")
local contextal_map = {
SPAM = 'CONTEXTAL_SPAM',
QUARANTINE = 'CONTEXTAL_QUARANTINE',
BLOCK = 'CONTEXTAL_BLOCK',
}

local contextal_callback = function(task)
local logger = require "rspamd_logger"
local filename = task:store_in_file()
local command = string.format('"%s" --actions-priority ALLOW,BLOCK,QUARANTINE,SPAM --ignored-actions ALLOW "%s"', ctx_scan_path, filename)
local handle = io.popen(command)
if (handle == nil) then
logger.err(task, "popen failed")
return false
end
local output = handle:read("*a")
if (re_action_clean:match(output)) then
logger.infox(task, "Clean")
return false
end
local match = re_action_infected:search(output, false, true)
if match == nil then
logger.err(task, "Unexpected ctx-scan output: %s", output)
return false
end
local contextal_action = match[1][2]
local symbol = contextal_map[contextal_action]
if (symbol == nil) then
logger.err(task, "Unexpected action: %s", contextal_action)
return false
end
logger.infox(task, "Return symbol %s", symbol)
task:insert_result(symbol, 1.0)
end

local id = rspamd_config:register_symbol({
name = 'CONTEXTAL_CALLBACK',
type = 'callback',
callback = contextal_callback
})
rspamd_config:register_symbol({
name = 'CONTEXTAL_SPAM',
flags = 'nice',
parent = id,
score = 1.0,
type = 'virtual'
})
rspamd_config:register_symbol({
name = 'CONTEXTAL_QUARANTINE',
flags = 'nice',
parent = id,
score = 1.0,
type = 'virtual'
})
rspamd_config:register_symbol({
name = 'CONTEXTAL_BLOCK',
flags = 'nice',
parent = id,
score = 1.0,
type = 'virtual'
})

4. Configure Force Actions module in /etc/rspamd/local.d/force_actions.conf:

rules {
CONTEXTAL_SPAM {
action = "add header"
expression = "CONTEXTAL_SPAM"
honor_action = ["reject", "soft reject", "quarantine"]
}
CONTEXTAL_QUARANTINE {
# if your MTA does not support "quarantine" use "reject" or "soft reject"
action = "quarantine"
expression = "CONTEXTAL_QUARANTINE"
honor_action = ["reject"]
}
CONTEXTAL_BLOCK {
action = "reject"
expression = "CONTEXTAL_BLOCK"
}
}

5. Restart Rspamd.