From 555fbb78c46ead295e1a9a73d38720dc05159fe2 Mon Sep 17 00:00:00 2001 From: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com> Date: Wed, 25 Jan 2023 10:28:59 +0100 Subject: [PATCH] feature: provide better rspamd suppport (#3016) * added options to toggle OpenDKIM & OpenDMARC rspamd can provide DKIM signing and DMARC checking itself, so users should be able to disable OpenDKIM & OpenDMARC. The default is left at 1, so users have to to opt-in when the want to disable the features. * misc small enhancements * adjusted start of rspamd The order of starting redis + rspamd was reversed (now correct) and rspamd now starts with the correct user. * adjusted rspamd core configuration The main configuration was revised. This includes AV configuration as well as worker/proxy/controller configuration used to control the main rspamd processes. The configuration is not tested extensively, but well enough that I am confident to go forward with it until we declare rspamd support as stable. * update & improve the documentation * add tests These are some initial tests which test the most basic functionality. * tests(refactor): Improve consistency and documentation for test helpers (#3012) * added `ALWAYS_RUN` target `Makefile` recipies (#3013) This ensures the recipies are always run. Co-authored-by: georglauterbach <44545919+georglauterbach@users.noreply.github.com> * adjusted rspamd test to refactored test helper functions * improve documentation * apply suggestions from code review (no. 1 by @polarthene) Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com> * streamline heredoc (EOM -> EOF) * adjust rspamd test (remove unnecessary run arguments) Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com> --- docs/content/config/environment.md | 33 +++++-- docs/content/config/security/rspamd.md | 38 ++++++++ docs/mkdocs.yml | 1 + mailserver.env | 14 +++ target/postfix/main.cf | 4 +- target/rspamd/local.d/actions.conf | 3 + target/rspamd/local.d/antivirus.conf | 13 +++ target/rspamd/local.d/disabled/antivirus.conf | 10 -- target/rspamd/local.d/logging.inc | 4 +- target/rspamd/local.d/worker-controller.inc | 3 + target/rspamd/local.d/worker-normal.inc | 4 + target/rspamd/local.d/worker-proxy.inc | 18 ++++ target/scripts/helpers/variables.sh | 2 + target/scripts/start-mailserver.sh | 8 +- target/scripts/startup/misc-stack.sh | 1 - target/scripts/startup/setup-stack.sh | 83 ++++++++++++---- target/scripts/update-check.sh | 4 +- target/supervisor/conf.d/supervisor-app.conf | 2 +- .../email-templates/rspamd-spam.txt | 13 +++ .../email-templates/rspamd-virus.txt | 12 +++ .../parallel/set1/spam_virus/rspamd.bats | 96 +++++++++++++++++++ .../parallel/set3/process-check-restart.bats | 8 +- 22 files changed, 324 insertions(+), 50 deletions(-) create mode 100644 docs/content/config/security/rspamd.md create mode 100644 target/rspamd/local.d/actions.conf create mode 100644 target/rspamd/local.d/antivirus.conf delete mode 100644 target/rspamd/local.d/disabled/antivirus.conf create mode 100644 target/rspamd/local.d/worker-controller.inc create mode 100644 target/rspamd/local.d/worker-normal.inc create mode 100644 target/rspamd/local.d/worker-proxy.inc create mode 100644 test/test-files/email-templates/rspamd-spam.txt create mode 100644 test/test-files/email-templates/rspamd-virus.txt create mode 100644 test/tests/parallel/set1/spam_virus/rspamd.bats diff --git a/docs/content/config/environment.md b/docs/content/config/environment.md index 600fd434..f7187ccc 100644 --- a/docs/content/config/environment.md +++ b/docs/content/config/environment.md @@ -71,20 +71,18 @@ Set the timezone. If this variable is unset, the container runtime will try to d ##### ENABLE_RSPAMD +Enable or disable Rspamd. + !!! warning "Current State" - Rspamd-support is under active development. Be aware that breaking changes can happen at any time. Moreover, you will _currently_ need to adjust Postfix's configuration _yourself_ if you want to use Rspamd; you may use [`user-patches.sh`][docs-userpatches]. + Rspamd-support is under active development. Be aware that breaking changes can happen at any time. - You will need to add Rspamd to the `smtpd_milters` in Postfix's `main.cf`. This can easily be done with `sed`: `sed -i -E 's|^(smtpd_milters = .*)|\1,inet:localhost:11332|g' /etc/postfix/main.cf`. Moreover, have a look at the [integration of Rspamd into Postfx](https://rspamd.com/doc/integration.html). You will need to provide additional configuration files at the moment (to `/etc/rspamd/local.d/`) to make Rspamd run in milter-mode. + Currently, rspamd is integrated into Postfix as a milter. However, there is no official DKIM/DMARC support for rspamd in DMS as of now (WIP). To get more information, see [the detailed documentation page for Rspamd][docs-rspamd]. -[docs-userpatches]: ./advanced/override-defaults/user-patches.md - -!!! bug "Rspamd and DNS Block Lists" +!!! warning "Rspamd and DNS Block Lists" When you use Rspamd, you might want to use the [RBL module](https://rspamd.com/doc/modules/rbl.html). If you do, make sure your DNS resolver is set up correctly (i.e. it should be a non-public recursive resolver). Otherwise, you [might not be able](https://www.spamhaus.org/faq/section/DNSBL%20Usage#365) to make use of the block lists. -Enable or disable Rspamd. - - **0** => disabled - 1 => enabled @@ -114,16 +112,30 @@ Note: Emails will be rejected, if they don't pass the block list checks! - **0** => DNS block lists are disabled - 1 => DNS block lists are enabled -##### ENABLE_CLAMAV +##### ENABLE_OPENDKIM -- **0** => ClamAV is disabled -- 1 => ClamAV is enabled +Enables the OpenDKIM service. + +- **1** => Enabled +- 0 => Disabled + +##### ENABLE_OPENDMARC + +Enables the OpenDMARC service. + +- **1** => Enabled +- 0 => Disabled ##### ENABLE_POP3 - **empty** => POP3 service disabled - 1 => Enables POP3 service +##### ENABLE_CLAMAV + +- **0** => ClamAV is disabled +- 1 => ClamAV is enabled + ##### ENABLE_FAIL2BAN - **0** => fail2ban service disabled @@ -776,6 +788,7 @@ you to replace both instead of just the envelope sender. - **empty** => no default - password for default relay user +[docs-rspamd]: ./security/rspamd.md [docs-faq-onedir]: ../faq.md#what-about-docker-datadmsmail-state-folder-varmail-state-internally [docs-tls]: ./security/ssl.md [docs-tls-letsencrypt]: ./security/ssl.md#lets-encrypt-recommended diff --git a/docs/content/config/security/rspamd.md b/docs/content/config/security/rspamd.md new file mode 100644 index 00000000..9e5183fe --- /dev/null +++ b/docs/content/config/security/rspamd.md @@ -0,0 +1,38 @@ +--- +title: 'Security | Rspamd' +--- + +!!! warning "Implementation of Rspamd into DMS is WIP!" + +## About + +Rspamd is a "fast, free and open-source spam filtering system". It offers high performance as it is written in C. Visit [their homepage][homepage] for more details. + +## Integration & Configuration + +We provide a very simple but easy to maintain setup of RSpamd. The proxy worker operates in [self-scan mode][proxy-self-scan-mode]. This simplifies the setup as we do not require a normal worker. You can easily change this though by [overriding the configuration by DMS](#providing-overriding-settings). + +### Providing & Overriding Settings + +DMS brings sane default settings for Rspamd. They are located at `/etc/rspamd/local.d/` inside the container (or `target/rspamd/local.d/` in the repository). If you want to change these settings and / or provide your own settings, you can + +1. place files at `/etc/rspamd/override.d/` which will override Rspamd settings and DMS settings +2. (re-)place files at `/etc/rspamd/local.d/` to override DMS settings and merge them with Rspamd settings + +You can find a list of all Rspamd modules [on their website][modules]. + +### DMS' Defaults + +You can choose to enable ClamAV, and Rspamd will then use it to check for viruses. Just set the environment variable `ENABLE_CLAMAV=1`. + +DMS disables certain modules (clickhouse, dkim_signing, elastic, greylist, rbl, reputation, spamassassin, url_redirector, metric_exporter) by default. We believe these are not required in a standard setup, and needlessly use resources. You can re-activate them by replacing `/etc/rspamd/local.d/.conf` or overriding DMS' default with `/etc/rspamd/override.d/.conf`. + +DMS does not set a default password for the controller worker. You may want to do that yourself. In setup where you already have an authentication provider in front of the Rspamd webpage, you may add `secure_ip = "0.0.0.0/0";` to `worker-controller.inc` to disable password authentication inside Rspamd completely. + +## Missing in DMS' Current Implementation + +We currently lack easy integration for DKIM signing. We use OpenDKIM though which should work just as well. If you want to use Rspamd for DKIM signing, you need to provide all settings yourself and probably also set the environment `ENABLE_OPENKIM=0`. Do not confuse the signing with checking DKIM signatures of other emails: Rspamd will check signatures from other emails, just not sign yours in the default configuration. + +[homepage]: https://rspamd.com/ +[modules]: https://rspamd.com/doc/modules/ +[proxy-self-scan-mode]: https://rspamd.com/doc/workers/rspamd_proxy.html#self-scan-mode diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 08e11557..d16423d5 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -127,6 +127,7 @@ nav: - 'SSL/TLS': config/security/ssl.md - 'Fail2Ban': config/security/fail2ban.md - 'Mail Encryption' : config/security/mail_crypt.md + - 'Rspamd' : config/security/rspamd.md - 'Troubleshooting': - 'Debugging': config/troubleshooting/debugging.md - 'Mail Delivery with POP3': config/pop3.md diff --git a/mailserver.env b/mailserver.env index afc19137..4ad776e5 100644 --- a/mailserver.env +++ b/mailserver.env @@ -98,9 +98,23 @@ SPOOF_PROTECTION= # - 1 => Enabled ENABLE_SRS=0 +# Enables the OpenDKIM service. +# **1** => Enabled +# 0 => Disabled +ENABLE_OPENDKIM=1 + +# Enables the OpenDMARC service. +# **1** => Enabled +# 0 => Disabled +ENABLE_OPENDMARC=1 + # 1 => Enables POP3 service # empty => disables POP3 ENABLE_POP3= + +# Enables ClamAV, and anti-virus scanner. +# 1 => Enabled +# **0** => Disabled ENABLE_CLAMAV=0 # Enables Rspamd diff --git a/target/postfix/main.cf b/target/postfix/main.cf index 0ed3a357..c42bd980 100644 --- a/target/postfix/main.cf +++ b/target/postfix/main.cf @@ -93,8 +93,8 @@ milter_protocol = 6 milter_default_action = accept dkim_milter = inet:localhost:8891 dmarc_milter = inet:localhost:8893 -smtpd_milters = $dkim_milter,$dmarc_milter -non_smtpd_milters = $dkim_milter +smtpd_milters = +non_smtpd_milters = # SPF policy settings policyd-spf_time_limit = 3600 diff --git a/target/rspamd/local.d/actions.conf b/target/rspamd/local.d/actions.conf new file mode 100644 index 00000000..38632624 --- /dev/null +++ b/target/rspamd/local.d/actions.conf @@ -0,0 +1,3 @@ +# documentation: https://rspamd.com/doc/configuration/metrics.html#actions + +subject = "***SPAM*** %s" diff --git a/target/rspamd/local.d/antivirus.conf b/target/rspamd/local.d/antivirus.conf new file mode 100644 index 00000000..2ce4e96f --- /dev/null +++ b/target/rspamd/local.d/antivirus.conf @@ -0,0 +1,13 @@ +# documentation: https://rspamd.com/doc/modules/antivirus.html + +enabled = false; + +ClamAV { + type = "clamav"; + servers = "/var/run/clamav/clamd.ctl"; + action = "reject"; + message = '${SCANNER} FOUND VIRUS "${VIRUS}"'; + scan_mime_parts = false; + symbol = "CLAM_VIRUS"; + log_clean = true; +} diff --git a/target/rspamd/local.d/disabled/antivirus.conf b/target/rspamd/local.d/disabled/antivirus.conf deleted file mode 100644 index fc4acc7b..00000000 --- a/target/rspamd/local.d/disabled/antivirus.conf +++ /dev/null @@ -1,10 +0,0 @@ -# documentation: https://rspamd.com/doc/modules/antivirus.html - -ClamAV { - action = "reject"; - scan_mime_parts = true; - message = '${SCANNER}: virus found: "${VIRUS}"'; - type = "clamav"; - log_clean = false; - servers = "127.0.0.1:3310"; -} diff --git a/target/rspamd/local.d/logging.inc b/target/rspamd/local.d/logging.inc index 8c029142..383b13c6 100644 --- a/target/rspamd/local.d/logging.inc +++ b/target/rspamd/local.d/logging.inc @@ -1,6 +1,6 @@ # documentation: https://rspamd.com/doc/configuration/logging.html type = "console"; -level = "notice"; -color = true; +level = "silent"; +color = false; systemd = false; diff --git a/target/rspamd/local.d/worker-controller.inc b/target/rspamd/local.d/worker-controller.inc new file mode 100644 index 00000000..31c4b340 --- /dev/null +++ b/target/rspamd/local.d/worker-controller.inc @@ -0,0 +1,3 @@ +# documentation: https://rspamd.com/doc/workers/controller.html + +bind_socket = "0.0.0.0:11334"; diff --git a/target/rspamd/local.d/worker-normal.inc b/target/rspamd/local.d/worker-normal.inc new file mode 100644 index 00000000..c3aa543c --- /dev/null +++ b/target/rspamd/local.d/worker-normal.inc @@ -0,0 +1,4 @@ +# documentation: https://rspamd.com/doc/workers/normal.html + +enabled = false; +bind_socket = "127.0.0.1:11333"; diff --git a/target/rspamd/local.d/worker-proxy.inc b/target/rspamd/local.d/worker-proxy.inc new file mode 100644 index 00000000..02c711d3 --- /dev/null +++ b/target/rspamd/local.d/worker-proxy.inc @@ -0,0 +1,18 @@ +# documentation: https://rspamd.com/doc/workers/rspamd_proxy.html +# see also: https://rspamd.com/doc/quickstart.html#using-of-milter-protocol-for-rspamd--16 + +bind_socket = "127.0.0.1:11332"; + +milter = yes; +timeout = 120s; + +upstream "local" { + default = yes; + self_scan = yes; +} + +count = 2; +max_retries = 5; +discard_on_reject = false; +quarantine_on_reject = false; +spam_header = "X-Spam"; diff --git a/target/scripts/helpers/variables.sh b/target/scripts/helpers/variables.sh index e7cf7a61..d224465d 100644 --- a/target/scripts/helpers/variables.sh +++ b/target/scripts/helpers/variables.sh @@ -88,6 +88,8 @@ function _environment_variables_general_setup VARS[ENABLE_FAIL2BAN]="${ENABLE_FAIL2BAN:=0}" VARS[ENABLE_FETCHMAIL]="${ENABLE_FETCHMAIL:=0}" VARS[ENABLE_MANAGESIEVE]="${ENABLE_MANAGESIEVE:=0}" + VARS[ENABLE_OPENDKIM]="${ENABLE_OPENDKIM:=1}" + VARS[ENABLE_OPENDMARC]="${ENABLE_OPENDMARC:=1}" VARS[ENABLE_POP3]="${ENABLE_POP3:=0}" VARS[ENABLE_POSTGREY]="${ENABLE_POSTGREY:=0}" VARS[ENABLE_QUOTAS]="${ENABLE_QUOTAS:=1}" diff --git a/target/scripts/start-mailserver.sh b/target/scripts/start-mailserver.sh index 795b5129..170b2904 100755 --- a/target/scripts/start-mailserver.sh +++ b/target/scripts/start-mailserver.sh @@ -103,7 +103,7 @@ function _register_functions [[ ${CLAMAV_MESSAGE_SIZE_LIMIT} != '25M' ]] && _register_setup_function '_setup_clamav_sizelimit' [[ ${ENABLE_RSPAMD} -eq 1 ]] && _register_setup_function '_setup_rspamd' - _register_setup_function '_setup_dkim' + _register_setup_function '_setup_dkim_dmarc' _register_setup_function '_setup_ssl' _register_setup_function '_setup_docker_permit' _register_setup_function '_setup_mailname' @@ -167,13 +167,13 @@ function _register_functions if [[ ${ENABLE_RSPAMD} -eq 1 ]] then - _register_start_daemon '_start_daemon_rspamd' _register_start_daemon '_start_daemon_redis' + _register_start_daemon '_start_daemon_rspamd' fi # needs to be started before SASLauthd - _register_start_daemon '_start_daemon_opendkim' - _register_start_daemon '_start_daemon_opendmarc' + [[ ${ENABLE_OPENDKIM} -eq 1 ]] && _register_start_daemon '_start_daemon_opendkim' + [[ ${ENABLE_OPENDMARC} -eq 1 ]] && _register_start_daemon '_start_daemon_opendmarc' # needs to be started before postfix [[ ${ENABLE_POSTGREY} -eq 1 ]] && _register_start_daemon '_start_daemon_postgrey' diff --git a/target/scripts/startup/misc-stack.sh b/target/scripts/startup/misc-stack.sh index ca014453..f723e1e0 100644 --- a/target/scripts/startup/misc-stack.sh +++ b/target/scripts/startup/misc-stack.sh @@ -35,7 +35,6 @@ function _misc_save_states [[ ${ENABLE_FETCHMAIL} -eq 1 ]] && FILES+=('lib/fetchmail') [[ ${ENABLE_POSTGREY} -eq 1 ]] && FILES+=('lib/postgrey') [[ ${ENABLE_RSPAMD} -eq 1 ]] && FILES+=('lib/rspamd') - # [[ ${ENABLE_RSPAMD} -eq 1 ]] && FILES+=('lib/redis') [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && FILES+=('lib/spamassassin') [[ ${SMTP_ONLY} -ne 1 ]] && FILES+=('lib/dovecot') diff --git a/target/scripts/startup/setup-stack.sh b/target/scripts/startup/setup-stack.sh index f560e09d..3985bf1b 100644 --- a/target/scripts/startup/setup-stack.sh +++ b/target/scripts/startup/setup-stack.sh @@ -84,8 +84,15 @@ function _setup_amavis mv /etc/cron.d/amavisd-new /etc/cron.d/amavisd-new.disabled chmod 0 /etc/cron.d/amavisd-new.disabled - [[ ${ENABLE_CLAMAV} -eq 1 ]] && _log 'warn' 'ClamAV will not work when Amavis is disabled. Remove ENABLE_AMAVIS=0 from your configuration to fix it.' - [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && _log 'warn' 'Spamassassin will not work when Amavis is disabled. Remove ENABLE_AMAVIS=0 from your configuration to fix it.' + if [[ ${ENABLE_CLAMAV} -eq 1 ]] && [[ ${ENABLE_RSPAMD} -eq 0 ]] + then + _log 'warn' 'ClamAV will not work when Amavis & rspamd are disabled. Enable either Amavis or rspamd to fix it.' + fi + + if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] + then + _log 'warn' 'Spamassassin will not work when Amavis is disabled. Enable Amavis to fix it.' + fi fi } @@ -95,19 +102,45 @@ function _setup_rspamd if [[ ${ENABLE_AMAVIS} -eq 1 ]] || [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] then - _shutdown 'You cannot run Amavis/SpamAssassin and Rspamd at the same time' + _log 'warn' 'Running rspamd at the same time as Amavis or SpamAssassin is discouraged' fi if [[ ${ENABLE_CLAMAV} -eq 1 ]] then _log 'debug' 'Rspamd will use ClamAV' - mv /etc/rspamd/local.d/disabled/antivirus.conf /etc/rspamd/local.d/antivirus.conf + sedfile -i -E 's|^(enabled).*|\1 = true;|g' /etc/rspamd/local.d/antivirus.conf + # RSpamd uses ClamAV's UNIX socket, and to be able to read it, it must be in the same group + usermod -a -G clamav _rspamd else _log 'debug' 'Rspamd will not use ClamAV (which has not been enabled)' fi - _log 'warn' 'Only running with default configuration' - _log 'warn' 'You will need to adjust the Postfix configuration yourself to use Rspamd as of now' + declare -a DISABLE_MODULES + DISABLE_MODULES=( + clickhouse + dkim_signing + elastic + greylist + rbl + reputation + spamassassin + url_redirector + metric_exporter + ) + + for MODULE in "${DISABLE_MODULES[@]}" + do + cat >"/etc/rspamd/local.d/${MODULE}.conf" << EOF +#documentation: https://rspamd.com/doc/modules/${MODULE}.html + +enabled = false; + +EOF + done + + # shellcheck disable=SC2016 + sed -i -E 's|^(smtpd_milters =.*)|\1 inet:localhost:11332|g' /etc/postfix/main.cf + touch /var/lib/rspamd/stats.ucl } function _setup_dmarc_hostname @@ -580,7 +613,7 @@ EOF -e "/dovecot_destination_recipient_limit =.*/d" \ /etc/postfix/main.cf - gpasswd -a postfix sasl + gpasswd -a postfix sasl >/dev/null } function _setup_postfix_aliases @@ -599,18 +632,36 @@ function _setup_SRS postconf 'recipient_canonical_classes = envelope_recipient,header_recipient' } -function _setup_dkim +function _setup_dkim_dmarc { + if [[ ${ENABLE_OPENDMARC} -eq 1 ]] + then + _log 'trace' "Adding OpenDMARC to Postfix's milters" + + # shellcheck disable=SC2016 + sed -i -E 's|^(smtpd_milters =.*)|\1 \$dmarc_milter|g' /etc/postfix/main.cf + fi + + [[ ${ENABLE_OPENDKIM} -eq 1 ]] || return 0 + _log 'debug' 'Setting up DKIM' - mkdir -p /etc/opendkim && touch /etc/opendkim/SigningTable + mkdir -p /etc/opendkim/keys/ && touch /etc/opendkim/SigningTable + + _log 'trace' "Adding OpenDKIM to Postfix's milters" + # shellcheck disable=SC2016 + sed -i -E 's|^(smtpd_milters =.*)|\1 \$dkim_milter|g' /etc/postfix/main.cf + # shellcheck disable=SC2016 + sed -i -E 's|^(non_smtpd_milters =.*)|\1 \$dkim_milter|g' /etc/postfix/main.cf # check if any keys are available if [[ -e "/tmp/docker-mailserver/opendkim/KeyTable" ]] then cp -a /tmp/docker-mailserver/opendkim/* /etc/opendkim/ - _log 'trace' "DKIM keys added for: $(ls /etc/opendkim/keys/)" + local KEYS + KEYS=$(find /etc/opendkim/keys/ -type f -maxdepth 1) + _log 'trace' "DKIM keys added for: ${KEYS}" _log 'trace' "Changing permissions on '/etc/opendkim'" chown -R opendkim:opendkim /etc/opendkim/ @@ -889,7 +940,7 @@ function _setup_security_stack sa-update --import /etc/spamassassin/kam/kam.sa-channels.mcgrail.com.key - cat >"${SPAMASSASSIN_KAM_CRON_FILE}" <<"EOM" + cat >"${SPAMASSASSIN_KAM_CRON_FILE}" <<"EOF" #!/bin/bash RESULT=$(sa-update --gpgkey 24C063D8 --channel kam.sa-channels.mcgrail.com 2>&1) @@ -904,7 +955,7 @@ fi exit 0 -EOM +EOF chmod +x "${SPAMASSASSIN_KAM_CRON_FILE}" fi @@ -1003,11 +1054,11 @@ function _setup_mail_summary _log 'debug' "${ENABLED_MESSAGE}" _log 'trace' 'Creating daily cron job for pflogsumm report' - cat >/etc/cron.daily/postfix-summary << EOM + cat >/etc/cron.daily/postfix-summary << EOF #!/bin/bash /usr/local/bin/report-pflogsumm-yesterday ${HOSTNAME} ${PFLOGSUMM_RECIPIENT} ${PFLOGSUMM_SENDER} -EOM +EOF chmod +x /etc/cron.daily/postfix-summary ;; @@ -1051,11 +1102,11 @@ function _setup_logwatch INTERVAL="--range 'between -7 days and -1 days'" fi - cat >"${LOGWATCH_FILE}" << EOM + cat >"${LOGWATCH_FILE}" << EOF #!/bin/bash /usr/sbin/logwatch ${INTERVAL} --hostname ${HOSTNAME} --mailto ${LOGWATCH_RECIPIENT} -EOM +EOF chmod 744 "${LOGWATCH_FILE}" ;; diff --git a/target/scripts/update-check.sh b/target/scripts/update-check.sh index fb1294ad..bdcc51b2 100755 --- a/target/scripts/update-check.sh +++ b/target/scripts/update-check.sh @@ -30,7 +30,7 @@ do if dpkg --compare-versions "${VERSION}" lt "${LATEST}" then # send mail notification to postmaster - read -r -d '' MAIL << EOM + read -r -d '' MAIL << EOF Hello ${POSTMASTER_ADDRESS}! There is a docker-mailserver update available on your host: $(hostname -f) @@ -39,7 +39,7 @@ Current version: ${VERSION} Latest version: ${LATEST} Changelog: ${CHANGELOG_URL} -EOM +EOF _log_with_date 'info' "Update available [ ${VERSION} --> ${LATEST} ]" diff --git a/target/supervisor/conf.d/supervisor-app.conf b/target/supervisor/conf.d/supervisor-app.conf index 0ffe3e1f..0378187b 100644 --- a/target/supervisor/conf.d/supervisor-app.conf +++ b/target/supervisor/conf.d/supervisor-app.conf @@ -103,7 +103,7 @@ autostart=false autorestart=true stdout_logfile=/var/log/supervisor/%(program_name)s.log stderr_logfile=/var/log/supervisor/%(program_name)s.log -command=/usr/bin/rspamd --no-fork --user=rspamd --group=rspamd +command=/usr/bin/rspamd --no-fork --user=_rspamd --group=_rspamd [program:redis] startsecs=0 diff --git a/test/test-files/email-templates/rspamd-spam.txt b/test/test-files/email-templates/rspamd-spam.txt new file mode 100644 index 00000000..2e6d566a --- /dev/null +++ b/test/test-files/email-templates/rspamd-spam.txt @@ -0,0 +1,13 @@ +HELO mail.example.test +MAIL FROM: spam@example.test +RCPT TO: user1@localhost.localdomain +DATA +From: Docker Mail Server +To: Existing Local User +Date: Sat, 21 Jan 2023 11:11:11 +0000 +Subject: Test Message rspamd-spam.txt +This is a test mail. +XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X + +. +QUIT diff --git a/test/test-files/email-templates/rspamd-virus.txt b/test/test-files/email-templates/rspamd-virus.txt new file mode 100644 index 00000000..cdacf9af --- /dev/null +++ b/test/test-files/email-templates/rspamd-virus.txt @@ -0,0 +1,12 @@ +HELO mail.example.test +MAIL FROM: virus@example.test +RCPT TO: user1@localhost.localdomain +DATA +From: Docker Mail Server +To: Existing Local User +Date: Sat, 21 Jan 2023 11:11:11 +0000 +Subject: Test Message rspamd-virus.txt +X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* + +. +QUIT diff --git a/test/tests/parallel/set1/spam_virus/rspamd.bats b/test/tests/parallel/set1/spam_virus/rspamd.bats new file mode 100644 index 00000000..f7c3608a --- /dev/null +++ b/test/tests/parallel/set1/spam_virus/rspamd.bats @@ -0,0 +1,96 @@ +load "${REPOSITORY_ROOT}/test/helper/setup" +load "${REPOSITORY_ROOT}/test/helper/common" + +BATS_TEST_NAME_PREFIX='[rspamd] ' +CONTAINER_NAME='dms-test_rspamd' + +function setup_file() { + _init_with_defaults + + # Comment for maintainers about `PERMIT_DOCKER=host`: + # https://github.com/docker-mailserver/docker-mailserver/pull/2815/files#r991087509 + local CUSTOM_SETUP_ARGUMENTS=( + --env ENABLE_CLAMAV=1 + --env ENABLE_RSPAMD=1 + --env ENABLE_OPENDKIM=0 + --env ENABLE_OPENDMARC=0 + --env PERMIT_DOCKER=host + --env LOG_LEVEL=trace + ) + + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' + + # wait for ClamAV to be fully setup or we will get errors on the log + _repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" test -e /var/run/clamav/clamd.ctl + + _wait_for_service redis + _wait_for_service rspamd + _wait_for_service postfix + _wait_for_smtp_port_in_container + + # We will send 3 emails: the first one should pass just fine; the second one should + # be rejected due to spam; the third one should be rejected due to a virus. + _run_in_container_bash "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt" + assert_success + _run_in_container_bash "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/rspamd-spam.txt" + assert_success + _run_in_container_bash "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/rspamd-virus.txt" + assert_success + + _wait_for_empty_mail_queue_in_container "${CONTAINER_NAME}" +} + +function teardown_file() { _default_teardown ; } + +@test "Postfix's main.cf was adjusted" { + _run_in_container grep -q 'smtpd_milters = inet:localhost:11332' /etc/postfix/main.cf + assert_success +} + +@test "logs exist and contains proper content" { + _should_contain_string_rspamd 'rspamd .* is loading configuration' + _should_contain_string_rspamd 'lua module clickhouse is disabled in the configuration' + _should_contain_string_rspamd 'lua module dkim_signing is disabled in the configuration' + _should_contain_string_rspamd 'lua module elastic is disabled in the configuration' + _should_contain_string_rspamd 'lua module rbl is disabled in the configuration' + _should_contain_string_rspamd 'lua module reputation is disabled in the configuration' + _should_contain_string_rspamd 'lua module spamassassin is disabled in the configuration' + _should_contain_string_rspamd 'lua module url_redirector is disabled in the configuration' + _should_contain_string_rspamd 'lua module metric_exporter is disabled in the configuration' +} + +@test "normal mail passes fine" { + _should_contain_string_rspamd 'F (no action)' + + run docker logs -n 100 "${CONTAINER_NAME}" + assert_success + assert_output --partial "stored mail into mailbox 'INBOX'" +} + +@test "detects and rejects spam" { + _should_contain_string_rspamd 'S (reject)' + _should_contain_string_rspamd 'reject "Gtube pattern"' + + run docker logs -n 100 "${CONTAINER_NAME}" + assert_success + assert_output --partial 'milter-reject' + assert_output --partial '5.7.1 Gtube pattern' +} + +@test "detects and rejects virus" { + _should_contain_string_rspamd 'T (reject)' + _should_contain_string_rspamd 'reject "ClamAV FOUND VIRUS "Eicar-Signature"' + + run docker logs -n 8 "${CONTAINER_NAME}" + assert_success + assert_output --partial 'milter-reject' + assert_output --partial '5.7.1 ClamAV FOUND VIRUS "Eicar-Signature"' + refute_output --partial "stored mail into mailbox 'INBOX'" +} + +function _should_contain_string_rspamd() { + local STRING=${1:?No string provided to _should_contain_string_rspamd} + + _run_in_container grep -q "${STRING}" /var/log/supervisor/rspamd.log + assert_success +} diff --git a/test/tests/parallel/set3/process-check-restart.bats b/test/tests/parallel/set3/process-check-restart.bats index 85bdfcd0..d30fc34e 100644 --- a/test/tests/parallel/set3/process-check-restart.bats +++ b/test/tests/parallel/set3/process-check-restart.bats @@ -34,8 +34,6 @@ function teardown() { _default_teardown ; } # These processes should always be running: CORE_PROCESS_LIST=( - opendkim - opendmarc master ) @@ -46,6 +44,8 @@ ENV_PROCESS_LIST=( dovecot fail2ban-server fetchmail + opendkim + opendmarc postgrey postsrsd saslauthd @@ -58,6 +58,8 @@ ENV_PROCESS_LIST=( --env ENABLE_CLAMAV=0 --env ENABLE_FAIL2BAN=0 --env ENABLE_FETCHMAIL=0 + --env ENABLE_OPENDKIM=0 + --env ENABLE_OPENDMARC=0 --env ENABLE_POSTGREY=0 --env ENABLE_SASLAUTHD=0 --env ENABLE_SRS=0 @@ -93,6 +95,8 @@ ENV_PROCESS_LIST=( --env ENABLE_AMAVIS=1 --env ENABLE_FAIL2BAN=1 --env ENABLE_FETCHMAIL=1 + --env ENABLE_OPENDKIM=1 + --env ENABLE_OPENDMARC=1 --env FETCHMAIL_PARALLEL=1 --env ENABLE_POSTGREY=1 --env ENABLE_SASLAUTHD=1