Rspamd: adjust learning of ham (#3334)

* adjust learning of ham

See #3333

When moving a mail from the Junk folder to the Trash folder, the mail
previously classified as ham due to the wildcard match of `*`. Because
the syntax does not allow for negation, we can only change the behavior
in a way that mails are learned as ham when they are moved into `INBOX`
from `Junk`. This is reasonable though.

* adjust tests accordingly

* adjust docs accordingly
This commit is contained in:
Georg Lauterbach 2023-05-13 13:59:16 +02:00 committed by GitHub
parent 78b7f0cbea
commit 9fd00bd6ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 30 deletions

View file

@ -353,7 +353,9 @@ Controls whether the [Rspamd Greylisting module][rspamd-greylisting-module] is e
When enabled, When enabled,
1. the "[autolearning][rspamd-autolearn]" feature is turned on; 1. the "[autolearning][rspamd-autolearn]" feature is turned on;
2. the Bayes classifier will be trained when moving mails from or to the Junk folder (with the help of Sieve scripts). 2. the Bayes classifier will be trained (with the help of Sieve scripts) when moving mails
1. from anywhere to the `Junk` folder (learning this email as spam);
2. from the `Junk` folder into the `INBOX` (learning this email as ham).
!!! warning "Attention" !!! warning "Attention"

View file

@ -222,13 +222,13 @@ function __rspamd__setup_learning
sedfile -i -E '/^}/d' /etc/dovecot/conf.d/90-sieve.conf sedfile -i -E '/^}/d' /etc/dovecot/conf.d/90-sieve.conf
cat >>/etc/dovecot/conf.d/90-sieve.conf << EOF cat >>/etc/dovecot/conf.d/90-sieve.conf << EOF
# From elsewhere to Junk folder # From anyhwere to Junk
imapsieve_mailbox1_name = Junk imapsieve_mailbox1_name = Junk
imapsieve_mailbox1_causes = COPY imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:${SIEVE_PIPE_BIN_DIR}/learn-spam.sieve imapsieve_mailbox1_before = file:${SIEVE_PIPE_BIN_DIR}/learn-spam.sieve
# From Junk folder to elsewhere # From Junk to Inbox
imapsieve_mailbox2_name = * imapsieve_mailbox2_name = INBOX
imapsieve_mailbox2_from = Junk imapsieve_mailbox2_from = Junk
imapsieve_mailbox2_causes = COPY imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:${SIEVE_PIPE_BIN_DIR}/learn-ham.sieve imapsieve_mailbox2_before = file:${SIEVE_PIPE_BIN_DIR}/learn-ham.sieve

View file

@ -1,4 +1,4 @@
A LOGIN user1@localhost.localdomain 123 A LOGIN user1@localhost.localdomain 123
B SELECT Junk B SELECT Junk
A UID MOVE 1:1 INBOX A MOVE 1:1 INBOX
A4 LOGOUT A LOGOUT

View file

@ -1,4 +1,4 @@
A LOGIN user1@localhost.localdomain 123 A LOGIN user1@localhost.localdomain 123
B SELECT INBOX B SELECT INBOX
A UID MOVE 1:1 Junk A MOVE 1:1 Junk
A4 LOGOUT A LOGOUT

View file

@ -237,14 +237,8 @@ function teardown_file() { _default_teardown ; }
_run_in_container grep -F 'sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe' "${SIEVE_CONFIG_FILE}" _run_in_container grep -F 'sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe' "${SIEVE_CONFIG_FILE}"
assert_success assert_success
# Move an email to the "Junk" folder from "INBOX"; the first email we local LEARN_SPAM_LINES=(
# sent should pass fine, hence we can now move it
_send_email 'nc_templates/rspamd_imap_move_to_junk' '0.0.0.0 143'
sleep 1 # wait for the transaction to finish
local MOVE_TO_JUNK_LINES=(
'imapsieve: mailbox Junk: MOVE event' 'imapsieve: mailbox Junk: MOVE event'
'imapsieve: Matched static mailbox rule [1]'
"sieve: file storage: script: Opened script \`learn-spam'" "sieve: file storage: script: Opened script \`learn-spam'"
'sieve: file storage: Using Sieve script path: /usr/lib/dovecot/sieve-pipe/learn-spam.sieve' 'sieve: file storage: Using Sieve script path: /usr/lib/dovecot/sieve-pipe/learn-spam.sieve'
"sieve: Executing script from \`/usr/lib/dovecot/sieve-pipe/learn-spam.svbin'" "sieve: Executing script from \`/usr/lib/dovecot/sieve-pipe/learn-spam.svbin'"
@ -254,20 +248,7 @@ function teardown_file() { _default_teardown ; }
"left message in mailbox 'Junk'" "left message in mailbox 'Junk'"
) )
_run_in_container cat /var/log/mail/mail.log local LEARN_HAM_LINES=(
assert_success
for LINE in "${MOVE_TO_JUNK_LINES[@]}"
do
assert_output --partial "${LINE}"
done
# Move an email to the "INBOX" folder from "Junk"; there should be two mails
# in the "Junk" folder
_send_email 'nc_templates/rspamd_imap_move_to_inbox' '0.0.0.0 143'
sleep 1 # wait for the transaction to finish
local MOVE_TO_JUNK_LINES=(
'imapsieve: Matched static mailbox rule [2]'
"sieve: file storage: script: Opened script \`learn-ham'" "sieve: file storage: script: Opened script \`learn-ham'"
'sieve: file storage: Using Sieve script path: /usr/lib/dovecot/sieve-pipe/learn-ham.sieve' 'sieve: file storage: Using Sieve script path: /usr/lib/dovecot/sieve-pipe/learn-ham.sieve'
"sieve: Executing script from \`/usr/lib/dovecot/sieve-pipe/learn-ham.svbin'" "sieve: Executing script from \`/usr/lib/dovecot/sieve-pipe/learn-ham.svbin'"
@ -275,9 +256,30 @@ function teardown_file() { _default_teardown ; }
"left message in mailbox 'INBOX'" "left message in mailbox 'INBOX'"
) )
# Move an email to the "Junk" folder from "INBOX"; the first email we
# sent should pass fine, hence we can now move it.
_send_email 'nc_templates/rspamd_imap_move_to_junk' '0.0.0.0 143'
sleep 1 # wait for the transaction to finish
_run_in_container cat /var/log/mail/mail.log _run_in_container cat /var/log/mail/mail.log
assert_success assert_success
for LINE in "${MOVE_TO_JUNK_LINES[@]}" assert_output --partial 'imapsieve: Matched static mailbox rule [1]'
refute_output --partial 'imapsieve: Matched static mailbox rule [2]'
for LINE in "${LEARN_SPAM_LINES[@]}"
do
assert_output --partial "${LINE}"
done
# Move an email to the "INBOX" folder from "Junk"; there should be two mails
# in the "Junk" folder, since the second email we sent during setup should
# have landed in the Junk folder already.
_send_email 'nc_templates/rspamd_imap_move_to_inbox' '0.0.0.0 143'
sleep 1 # wait for the transaction to finish
_run_in_container cat /var/log/mail/mail.log
assert_success
assert_output --partial 'imapsieve: Matched static mailbox rule [2]'
for LINE in "${LEARN_HAM_LINES[@]}"
do do
assert_output --partial "${LINE}" assert_output --partial "${LINE}"
done done