mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2025-08-04 18:15:29 +02:00
spam: use Sieve for rewriting subject with Rspamd & SA/Amavis (#3820)
This commit is contained in:
parent
3b11a8305e
commit
afb0093939
16 changed files with 262 additions and 179 deletions
|
@ -6,7 +6,11 @@
|
|||
# and to be able to explain the impact on the whole system.
|
||||
greylist = 4;
|
||||
add_header = 6;
|
||||
rewrite_subject = 7;
|
||||
reject = 11;
|
||||
|
||||
subject = "***SPAM*** %s"
|
||||
# The value `null` disabled the action. A subject rewrite is handled by `SPAM_SUBJECT`:
|
||||
# https://docker-mailserver.github.io/docker-mailserver/latest/config/environment/#spam_subject
|
||||
#
|
||||
# The reasoning for this can be found in
|
||||
# https://github.com/docker-mailserver/docker-mailserver/issues/3804
|
||||
rewrite_subject = null;
|
||||
|
|
|
@ -36,6 +36,7 @@ function _register_functions() {
|
|||
_register_check_function '_check_improper_restart'
|
||||
_register_check_function '_check_hostname'
|
||||
_register_check_function '_check_log_level'
|
||||
_register_check_function '_check_spam_prefix'
|
||||
|
||||
# ? >> Setup
|
||||
|
||||
|
@ -48,6 +49,7 @@ function _register_functions() {
|
|||
_register_setup_function '_setup_dovecot_sieve'
|
||||
_register_setup_function '_setup_dovecot_dhparam'
|
||||
_register_setup_function '_setup_dovecot_quota'
|
||||
_register_setup_function '_setup_spam_subject'
|
||||
_register_setup_function '_setup_spam_to_junk'
|
||||
_register_setup_function '_setup_spam_mark_as_read'
|
||||
fi
|
||||
|
|
|
@ -52,3 +52,11 @@ function _check_log_level() {
|
|||
LOG_LEVEL="${DEFAULT_LOG_LEVEL}"
|
||||
fi
|
||||
}
|
||||
|
||||
function _check_spam_prefix() {
|
||||
# This check should be independent of ENABLE_POP3 and ENABLE_IMAP
|
||||
if [[ ${MOVE_SPAM_TO_JUNK} -eq 0 ]] \
|
||||
&& [[ -z ${SPAM_SUBJECT} ]]; then
|
||||
_log 'warn' "'MOVE_SPAM_TO_JUNK=0' and 'SPAM_SUBJECT' is empty - make sure this is intended: spam e-mails might not be immediately recognizable in this configuration"
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -81,13 +81,9 @@ function __setup__security__spamassassin() {
|
|||
# shellcheck disable=SC2016
|
||||
sed -i -r 's|^\$sa_kill_level_deflt (.*);|\$sa_kill_level_deflt = '"${SA_KILL}"';|g' /etc/amavis/conf.d/20-debian_defaults
|
||||
|
||||
if [[ ${SA_SPAM_SUBJECT} == 'undef' ]]; then
|
||||
# shellcheck disable=SC2016
|
||||
sed -i -r 's|^\$sa_spam_subject_tag (.*);|\$sa_spam_subject_tag = undef;|g' /etc/amavis/conf.d/20-debian_defaults
|
||||
else
|
||||
# shellcheck disable=SC2016
|
||||
sed -i -r 's|^\$sa_spam_subject_tag (.*);|\$sa_spam_subject_tag = '"'${SA_SPAM_SUBJECT}'"';|g' /etc/amavis/conf.d/20-debian_defaults
|
||||
fi
|
||||
# disable rewriting the subject as this is handles by _setup_spam_subject (which uses Dovecot Sieve)
|
||||
# shellcheck disable=SC2016
|
||||
sed -i -r 's|^\$sa_spam_subject_tag (.*);|\$sa_spam_subject_tag = undef;|g' /etc/amavis/conf.d/20-debian_defaults
|
||||
|
||||
# activate short circuits when SA BAYES is certain it has spam or ham.
|
||||
if [[ ${SA_SHORTCIRCUIT_BAYES_SPAM} -eq 1 ]]; then
|
||||
|
@ -245,6 +241,57 @@ function __setup__security__amavis() {
|
|||
fi
|
||||
}
|
||||
|
||||
# If `SPAM_SUBJECT` is not empty, we create a Sieve script that alters the `Subject`
|
||||
# header, in order to prepend a user-defined string.
|
||||
function _setup_spam_subject() {
|
||||
if [[ -z ${SPAM_SUBJECT} ]]
|
||||
then
|
||||
_log 'debug' 'Spam subject is not set - no prefix will be added to spam e-mails'
|
||||
else
|
||||
_log 'debug' "Spam subject is set - the prefix '${SPAM_SUBJECT}' will be added to spam e-mails"
|
||||
|
||||
_log 'trace' "Enabling '+editheader' Sieve extension"
|
||||
# check whether sieve_global_extensions is disabled (and enabled it if so)
|
||||
sed -i -E 's|#(sieve_global_extensions.*)|\1|' /etc/dovecot/conf.d/90-sieve.conf
|
||||
# then append the extension
|
||||
sedfile -i -E 's|(sieve_global_extensions.*)|\1 +editheader|' /etc/dovecot/conf.d/90-sieve.conf
|
||||
|
||||
_log 'trace' "Adding global (before) Sieve script for subject rewrite"
|
||||
# This directory contains Sieve scripts that are executed before user-defined Sieve
|
||||
# scripts run.
|
||||
local DOVECOT_SIEVE_GLOBAL_BEFORE_DIR='/usr/lib/dovecot/sieve-global/before'
|
||||
local DOVECOT_SIEVE_FILE='spam_subject'
|
||||
readonly DOVECOT_SIEVE_GLOBAL_BEFORE_DIR DOVECOT_SIEVE_FILE
|
||||
|
||||
mkdir -p "${DOVECOT_SIEVE_GLOBAL_BEFORE_DIR}"
|
||||
# ref: https://superuser.com/a/1502589
|
||||
cat >"${DOVECOT_SIEVE_GLOBAL_BEFORE_DIR}/${DOVECOT_SIEVE_FILE}.sieve" << EOF
|
||||
require ["editheader","variables"];
|
||||
|
||||
if anyof (header :contains "X-Spam-Flag" "YES",
|
||||
header :contains "X-Spam" "Yes")
|
||||
{
|
||||
# Match the entire subject ...
|
||||
if header :matches "Subject" "*" {
|
||||
# ... to get it in a match group that can then be stored in a variable:
|
||||
set "subject" "\${1}";
|
||||
}
|
||||
|
||||
# We can't "replace" a header, but we can delete (all instances of) it and
|
||||
# re-add (a single instance of) it:
|
||||
deleteheader "Subject";
|
||||
|
||||
# Note that the header is added ":last" (so it won't appear before possible
|
||||
# "Received" headers).
|
||||
addheader :last "Subject" "${SPAM_SUBJECT}\${subject}";
|
||||
}
|
||||
EOF
|
||||
|
||||
sievec "${DOVECOT_SIEVE_GLOBAL_BEFORE_DIR}/${DOVECOT_SIEVE_FILE}.sieve"
|
||||
chown dovecot:root "${DOVECOT_SIEVE_GLOBAL_BEFORE_DIR}/${DOVECOT_SIEVE_FILE}."{sieve,svbin}
|
||||
fi
|
||||
}
|
||||
|
||||
# We can use Sieve to move spam emails to the "Junk" folder.
|
||||
function _setup_spam_to_junk() {
|
||||
if [[ ${MOVE_SPAM_TO_JUNK} -eq 1 ]]; then
|
||||
|
|
|
@ -25,6 +25,12 @@ function __environment_variables_backwards_compatibility() {
|
|||
_log 'error' "The ENV for which LDAP host to connect to must include the URI scheme ('ldap://', 'ldaps://', 'ldapi://')"
|
||||
fi
|
||||
|
||||
if [[ -n ${SA_SPAM_SUBJECT:-} ]]; then
|
||||
_log 'warn' "'SA_SPAM_SUBJECT' has been renamed to 'SPAM_SUBJECT' - this warning will block startup on v15.0.0"
|
||||
_log 'info' "Copying value of 'SA_SPAM_SUBJECT' into 'SPAM_SUBJECT' if 'SPAM_SUBJECT' has not been set explicitly"
|
||||
SPAM_SUBJECT=${SPAM_SUBJECT:-${SA_SPAM_SUBJECT}}
|
||||
fi
|
||||
|
||||
# TODO this can be uncommented in a PR handling the HOSTNAME/DOMAINNAME issue
|
||||
# TODO see check_for_changes.sh and dns.sh
|
||||
# if [[ -n ${OVERRIDE_HOSTNAME:-} ]]
|
||||
|
@ -67,7 +73,7 @@ function __environment_variables_general_setup() {
|
|||
VARS[RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE]="${RSPAMD_HFILTER_HOSTNAME_UNKNOWN_SCORE:=6}"
|
||||
VARS[RSPAMD_LEARN]="${RSPAMD_LEARN:=0}"
|
||||
VARS[SA_KILL]=${SA_KILL:="10.0"}
|
||||
VARS[SA_SPAM_SUBJECT]=${SA_SPAM_SUBJECT:="***SPAM*** "}
|
||||
VARS[SPAM_SUBJECT]=${SPAM_SUBJECT:=}
|
||||
VARS[SA_TAG]=${SA_TAG:="2.0"}
|
||||
VARS[SA_TAG2]=${SA_TAG2:="6.31"}
|
||||
VARS[SPAMASSASSIN_SPAM_TO_INBOX]="${SPAMASSASSIN_SPAM_TO_INBOX:=1}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue