From 04f4ae4569a2b5dcaffb510cd09ef1fb6ba038a2 Mon Sep 17 00:00:00 2001 From: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com> Date: Fri, 5 Jan 2024 09:07:31 +0100 Subject: [PATCH 1/3] Rspamd: add custom symbol scores for SPF, DKIM & DMARC (#3726) --- CHANGELOG.md | 5 + Dockerfile | 1 + target/rspamd/local.d/actions.conf | 11 ++- target/rspamd/scores.d/policies_group.conf | 108 +++++++++++++++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 target/rspamd/scores.d/policies_group.conf diff --git a/CHANGELOG.md b/CHANGELOG.md index 842b60c1..bccbe0e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ All notable changes to this project will be documented in this file. The format > **Note**: Changes and additions listed here are contained in the `:edge` image tag. These changes may not be as stable as released changes. +### Updates + +- **Rspamd** ([#3726](https://github.com/docker-mailserver/docker-mailserver/pull/3726)): + - symbol scores for SPF, DKIM & DMARC were updated to more closely align with [RFC7489](https://www.rfc-editor.org/rfc/rfc7489#page-24); please note though that complete alignment is undesirable, because other symbols might be added as well, which changes the overall score calculation again, see [this issue](https://github.com/docker-mailserver/docker-mailserver/issues/3690#issuecomment-1866871996) + ## [v13.2.0](https://github.com/docker-mailserver/docker-mailserver/releases/tag/v13.2.0) ### Security diff --git a/Dockerfile b/Dockerfile index 4d0e3568..f9802c2a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -106,6 +106,7 @@ EOF # ----------------------------------------------- COPY target/rspamd/local.d/ /etc/rspamd/local.d/ +COPY target/rspamd/scores.d/* /etc/rspamd/scores.d/ # ----------------------------------------------- # --- LDAP & SpamAssassin's Cron ---------------- diff --git a/target/rspamd/local.d/actions.conf b/target/rspamd/local.d/actions.conf index b214c339..fb4c15b9 100644 --- a/target/rspamd/local.d/actions.conf +++ b/target/rspamd/local.d/actions.conf @@ -1,9 +1,12 @@ # documentation: https://rspamd.com/doc/configuration/metrics.html#actions # and https://rspamd.com/doc/configuration/metrics.html -#greylist = 4; -#add_header = 6; -#rewrite_subject = 7; -#reject = 15; +# These values work in conjunction with the symbol scores in +# `scores.d/*.conf`. When adjusting them, make sure to understand +# 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" diff --git a/target/rspamd/scores.d/policies_group.conf b/target/rspamd/scores.d/policies_group.conf new file mode 100644 index 00000000..5f9426e9 --- /dev/null +++ b/target/rspamd/scores.d/policies_group.conf @@ -0,0 +1,108 @@ +# Please refer to +# https://github.com/docker-mailserver/docker-mailserver/issues/3690 +# for understanding this file and its scores' values. + +symbols = { + # SPF + "R_SPF_ALLOW" { + weight = -1; + description = "SPF verification allows sending"; + groups = ["spf"]; + } + "R_SPF_NA" { + weight = 1.5; + description = "Missing SPF record"; + one_shot = true; + groups = ["spf"]; + } + "R_SPF_SOFTFAIL" { + weight = 2.5; + description = "SPF verification soft-failed"; + groups = ["spf"]; + } + "R_SPF_FAIL" { + weight = 4.5; + description = "SPF verification failed"; + groups = ["spf"]; + } + + "R_SPF_NEUTRAL" { # == R_SPF_NA + weight = 1.5; + description = "SPF policy is neutral"; + groups = ["spf"]; + } + "R_SPF_DNSFAIL" { # == R_SPF_SOFTFAIL + weight = 2.5; + description = "SPF DNS failure"; + groups = ["spf"]; + } + "R_SPF_PERMFAIL" { # == R_SPF_FAIL + weight = 4.5; + description = "SPF record is malformed or persistent DNS error"; + groups = ["spf"]; + } + + # DKIM + "R_DKIM_ALLOW" { + weight = -1; + description = "DKIM verification succeed"; + one_shot = true; + groups = ["dkim"]; + } + "R_DKIM_NA" { + weight = 0; + description = "Missing DKIM signature"; + one_shot = true; + groups = ["dkim"]; + } + "R_DKIM_TEMPFAIL" { + weight = 1.5; + description = "DKIM verification soft-failed"; + groups = ["dkim"]; + } + "R_DKIM_PERMFAIL" { + weight = 4.5; + description = "DKIM verification hard-failed (invalid)"; + groups = ["dkim"]; + } + + "R_DKIM_REJECT" { # == R_DKIM_PERMFAIL + weight = 4.5; + description = "DKIM verification failed"; + one_shot = true; + groups = ["dkim"]; + } + + # DMARC + "DMARC_NA" { + weight = 1; + description = "No DMARC record"; + groups = ["dmarc"]; + } + "DMARC_POLICY_QUARANTINE" { + weight = 1.5; + description = "DMARC quarantine policy"; + groups = ["dmarc"]; + } + "DMARC_POLICY_REJECT" { + weight = 2; + description = "DMARC reject policy"; + groups = ["dmarc"]; + } + + "DMARC_POLICY_ALLOW" { # no equivalent + weight = -1; + description = "DMARC permit policy"; + groups = ["dmarc"]; + } + "DMARC_POLICY_ALLOW_WITH_FAILURES" { # no equivalent + weight = -0.5; + description = "DMARC permit policy with DKIM/SPF failure"; + groups = ["dmarc"]; + } + "DMARC_POLICY_SOFTFAIL" { # == DMARC_POLICY_QUARANTINE + weight = 1.5; + description = "DMARC soft-failed"; + groups = ["dmarc"]; + } +} From 6082d5f8d04c353dc1f9de723f3acbdfb4a8fa32 Mon Sep 17 00:00:00 2001 From: Brennan Kinney <5098581+polarathene@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:18:30 +1300 Subject: [PATCH 2/3] chore: Disable `smtputf8` support in config directly (#3750) * chore: Disable `smtputf8` support in config This was always configured disabled at runtime, better to just set explicitly in `main.cf` unless config diverges when Dovecot is enabled to opt-out of this feature. --- CHANGELOG.md | 2 ++ target/postfix/main.cf | 3 +++ target/scripts/startup/setup.d/postfix.sh | 3 --- test/tests/parallel/set3/mta/smtp_delivery.bats | 4 ++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bccbe0e9..5f229530 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. The format ### Updates +- **Internal:** + - Postfix is now configured with `smtputf8_enable = no` in our default `main.cf` config (_instead of during container startup_). ([#3750](https://github.com/docker-mailserver/docker-mailserver/pull/3750)) - **Rspamd** ([#3726](https://github.com/docker-mailserver/docker-mailserver/pull/3726)): - symbol scores for SPF, DKIM & DMARC were updated to more closely align with [RFC7489](https://www.rfc-editor.org/rfc/rfc7489#page-24); please note though that complete alignment is undesirable, because other symbols might be added as well, which changes the overall score calculation again, see [this issue](https://github.com/docker-mailserver/docker-mailserver/issues/3690#issuecomment-1866871996) diff --git a/target/postfix/main.cf b/target/postfix/main.cf index 1dc7bdbc..495ad8a9 100644 --- a/target/postfix/main.cf +++ b/target/postfix/main.cf @@ -5,6 +5,9 @@ biff = no append_dot_mydomain = no readme_directory = no +# Disabled as not compatible with Dovecot +smtputf8_enable = no + # Basic configuration # myhostname = alias_maps = hash:/etc/aliases diff --git a/target/scripts/startup/setup.d/postfix.sh b/target/scripts/startup/setup.d/postfix.sh index 58998376..5aec8636 100644 --- a/target/scripts/startup/setup.d/postfix.sh +++ b/target/scripts/startup/setup.d/postfix.sh @@ -19,9 +19,6 @@ function _setup_postfix_early() { postconf "inet_protocols = ${POSTFIX_INET_PROTOCOLS}" fi - __postfix__log 'trace' "Disabling SMTPUTF8 support" - postconf 'smtputf8_enable = no' - __postfix__log 'trace' "Configuring SASLauthd" if [[ ${ENABLE_SASLAUTHD} -eq 1 ]] && [[ ! -f /etc/postfix/sasl/smtpd.conf ]]; then cat >/etc/postfix/sasl/smtpd.conf << EOF diff --git a/test/tests/parallel/set3/mta/smtp_delivery.bats b/test/tests/parallel/set3/mta/smtp_delivery.bats index 169f374a..f87f11ed 100644 --- a/test/tests/parallel/set3/mta/smtp_delivery.bats +++ b/test/tests/parallel/set3/mta/smtp_delivery.bats @@ -277,6 +277,10 @@ function _successful() { --protocol ESMTP \ --server mail.example.test \ --quit-after FIRST-EHLO + + # Ensure the output is actually related to what we want to refute against: + assert_output --partial 'EHLO mail.external.tld' + assert_output --partial '221 2.0.0 Bye' refute_output --partial 'SMTPUTF8' } From 0eb4ac771498e1eff91944e79c19c8605995bc07 Mon Sep 17 00:00:00 2001 From: Casper Date: Sat, 6 Jan 2024 17:07:00 +0100 Subject: [PATCH 3/3] tests: Replace `wc -l` with `grep -c` (#3752) --- CHANGELOG.md | 1 + .../parallel/set1/spam_virus/clamav.bats | 2 +- .../parallel/set3/scripts/setup_cli.bats | 20 +++++++++---------- test/tests/serial/tests.bats | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f229530..d8f8a0d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. The format ### Updates - **Internal:** + - tests: Replace `wc -l` with `grep -c` ([#3752](https://github.com/docker-mailserver/docker-mailserver/pull/3752)) - Postfix is now configured with `smtputf8_enable = no` in our default `main.cf` config (_instead of during container startup_). ([#3750](https://github.com/docker-mailserver/docker-mailserver/pull/3750)) - **Rspamd** ([#3726](https://github.com/docker-mailserver/docker-mailserver/pull/3726)): - symbol scores for SPF, DKIM & DMARC were updated to more closely align with [RFC7489](https://www.rfc-editor.org/rfc/rfc7489#page-24); please note though that complete alignment is undesirable, because other symbols might be added as well, which changes the overall score calculation again, see [this issue](https://github.com/docker-mailserver/docker-mailserver/issues/3690#issuecomment-1866871996) diff --git a/test/tests/parallel/set1/spam_virus/clamav.bats b/test/tests/parallel/set1/spam_virus/clamav.bats index 9232f90f..9c035f5b 100644 --- a/test/tests/parallel/set1/spam_virus/clamav.bats +++ b/test/tests/parallel/set1/spam_virus/clamav.bats @@ -33,7 +33,7 @@ function setup_file() { function teardown_file() { _default_teardown ; } @test 'log files exist at /var/log/mail directory' { - _run_in_container_bash "ls -1 /var/log/mail/ | grep -E 'clamav|freshclam|mail.log' | wc -l" + _run_in_container_bash "ls -1 /var/log/mail/ | grep -c -E 'clamav|freshclam|mail.log'" assert_success assert_output 3 } diff --git a/test/tests/parallel/set3/scripts/setup_cli.bats b/test/tests/parallel/set3/scripts/setup_cli.bats index dca61358..76f16dce 100644 --- a/test/tests/parallel/set3/scripts/setup_cli.bats +++ b/test/tests/parallel/set3/scripts/setup_cli.bats @@ -204,12 +204,12 @@ function teardown_file() { _default_teardown ; } run ./setup.sh -c "${CONTAINER_NAME}" quota set quota_user2 51M assert_failure - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -E '^quota_user@example.com\:12M\$' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -c -E '^quota_user@example.com\:12M\$' | grep 1" assert_success run ./setup.sh -c "${CONTAINER_NAME}" quota set quota_user@example.com 26M assert_success - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -E '^quota_user@example.com\:26M\$' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -c -E '^quota_user@example.com\:26M\$' | grep 1" assert_success run grep "quota_user2@example.com" "${TEST_TMP_CONFIG}/dovecot-quotas.cf" @@ -220,12 +220,12 @@ function teardown_file() { _default_teardown ; } @test "delquota" { run ./setup.sh -c "${CONTAINER_NAME}" quota set quota_user@example.com 12M assert_success - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -E '^quota_user@example.com\:12M\$' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -c -E '^quota_user@example.com\:12M\$' | grep 1" assert_success run ./setup.sh -c "${CONTAINER_NAME}" quota del unknown@domain.com assert_failure - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -E '^quota_user@example.com\:12M\$' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/dovecot-quotas.cf | grep -c -E '^quota_user@example.com\:12M\$' | grep 1" assert_success run ./setup.sh -c "${CONTAINER_NAME}" quota del quota_user@example.com @@ -260,13 +260,13 @@ function teardown_file() { _default_teardown ; } ./setup.sh -c "${CONTAINER_NAME}" relay add-domain example3.org smtp.relay.com 587 # check adding - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -e '^@example1.org\s\+\[smtp.relay1.com\]:2525' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -c -e '^@example1.org\s\+\[smtp.relay1.com\]:2525' | grep 1" assert_success # test default port - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -e '^@example2.org\s\+\[smtp.relay2.com\]:25' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -c -e '^@example2.org\s\+\[smtp.relay2.com\]:25' | grep 1" assert_success # test modifying - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -e '^@example3.org\s\+\[smtp.relay.com\]:587' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -c -e '^@example3.org\s\+\[smtp.relay.com\]:587' | grep 1" assert_success } @@ -276,16 +276,16 @@ function teardown_file() { _default_teardown ; } ./setup.sh -c "${CONTAINER_NAME}" relay add-auth example2.org smtp_user2 smtp_pass_new # test adding - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-sasl-password.cf | grep -e '^@example.org\s\+smtp_user:smtp_pass' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-sasl-password.cf | grep -c -e '^@example.org\s\+smtp_user:smtp_pass' | grep 1" assert_success # test updating - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-sasl-password.cf | grep -e '^@example2.org\s\+smtp_user2:smtp_pass_new' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-sasl-password.cf | grep -c -e '^@example2.org\s\+smtp_user2:smtp_pass_new' | grep 1" assert_success } @test "relay exclude-domain" { ./setup.sh -c "${CONTAINER_NAME}" relay exclude-domain example.org - run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -e '^@example.org\s*$' | wc -l | grep 1" + run /bin/sh -c "cat ${TEST_TMP_CONFIG}/postfix-relaymap.cf | grep -c -e '^@example.org\s*$' | grep 1" assert_success } diff --git a/test/tests/serial/tests.bats b/test/tests/serial/tests.bats index 26deb541..752e325e 100644 --- a/test/tests/serial/tests.bats +++ b/test/tests/serial/tests.bats @@ -264,7 +264,7 @@ EOF # @test "amavis: config overrides" { - _run_in_container_bash "grep 'Test Verification' /etc/amavis/conf.d/50-user | wc -l" + _run_in_container_bash "grep -c 'Test Verification' /etc/amavis/conf.d/50-user" assert_success assert_output 1 }