diff --git a/docs/content/config/security/mail_crypt.md b/docs/content/config/security/mail_crypt.md index 463e91f6..a53b3736 100644 --- a/docs/content/config/security/mail_crypt.md +++ b/docs/content/config/security/mail_crypt.md @@ -24,8 +24,8 @@ Official Dovecot documentation: https://doc.dovecot.org/configuration_manual/mai # Enables mail_crypt for all services (imap, pop3, etc) mail_plugins = $mail_plugins mail_crypt plugin { - mail_crypt_global_private_key = -# -mail_home = /var/mail/%d/%n/home/ -mail_location = maildir:/var/mail/%d/%n +# path of `mail_path`. + +# ref: https://doc.dovecot.org/main/core/config/mail_location.html#mail_driver +mail_driver = maildir +# ref: https://doc.dovecot.org/main/core/config/mail_location.html#mail_path +mail_path = /var/mail/%{user | domain}/%{user | username} +mail_home = /var/mail/%{user | domain}/%{user | username}/home # If you need to set multiple mailbox locations or want to change default # namespace settings, you can do it by defining namespace sections. @@ -206,7 +195,9 @@ mail_privileged_group = docker # Space separated list of plugins to load for all services. Plugins specific to # IMAP, LDA, etc. are added to this list in their own .conf files. -mail_plugins = $mail_plugins quota +mail_plugins { + quota = yes +} ## ## Mailbox handling optimizations @@ -214,7 +205,9 @@ mail_plugins = $mail_plugins quota # Mailbox list indexes can be used to optimize IMAP STATUS commands. They are # also required for IMAP NOTIFY extension to be enabled. -#mailbox_list_index = no +# +# ref: https://doc.dovecot.org/main/core/plugins/quota.html#driver-count +mailbox_list_index = yes # The minimum number of mails in a mailbox before updates are done to cache # file. This allows optimizing Dovecot's behavior to do less disk writes at diff --git a/target/dovecot/10-ssl.conf b/target/dovecot/10-ssl.conf index c52d21f5..12e23626 100644 --- a/target/dovecot/10-ssl.conf +++ b/target/dovecot/10-ssl.conf @@ -9,21 +9,21 @@ # dropping root privileges, so keep the key file unreadable by anyone but root. # These [snakeoil files actually exist](https://askubuntu.com/questions/396120/what-is-the-purpose-of-the-ssl-cert-snakeoil-key), but shouldn't ever be used in production! # As `SSL_TYPE` env is required by docker-mailserver, these "snakeoil" files will be replaced on container startup. -ssl_cert = @ +# - recompute quota: doveadm quota recalc -u @ - # Track the current quota usage in Dovecot’s index files. - quota = count:User quota +# The quota driver to use +# +# ref: https://doc.dovecot.org/main/core/plugins/quota.html#driver-count +quota_driver = count - # Use virtual sizes for count - quota_vsizes = yes +# The maximum message size to be saved +# +# Sync this setting with Postfix. +# +# ref: https://doc.dovecot.org/main/core/summaries/settings.html#quota_mail_size +quota_mail_size = 10000M - # define the maximum message size to be saved, sync with postfix - quota_max_mail_size = 10000M +# Default quota per mailbox +# +# Sync this setting with Postfix. +# +# ref: https://doc.dovecot.org/main/core/plugins/quota.html#quota-limits +quota_storage_size = 128M - # default quota per mailbox, sync with postfix - quota_rule = *:storage=128M +# Allow additional space when deleting messages +# +# ref: https://doc.dovecot.org/main/core/plugins/quota.html#quota_storage_extra +mailbox Trash { + quota_storage_extra = 50M +} - # allow user to delete messages - quota_rule2 = Trash:storage=+50M +# TODO describe +# +# ref: https://doc.dovecot.org/main/core/plugins/quota.html#quota-grace +quota_storage_grace = 10M - quota_grace = 10%% - # 10% is the default - quota_warning = storage=95%% quota-warning 95 %u %d - quota_warning2 = storage=80%% quota-warning 80 %u %d - quota_warning3 = -storage=100%% quota-warning below %u %d # user is no longer over quota +# Warnings +# +# ref: https://doc.dovecot.org/main/core/plugins/quota.html#quota-warning-scripts +quota user { + warning warn-80 { + quota_storage_percentage = 80 + execute quota-warning { + args = 80 %{user} + } + } + warning warn-95 { + quota_storage_percentage = 95 + execute quota-warning { + args = 95 %{user} + } + } - quota_status_success=DUNNO - quota_status_nouser=DUNNO - quota_status_overquota = "552 5.2.2 Mailbox is full" + warning warn-under { + quota_storage_percentage = 100 + # user is no longer over quota + threshold = under + execute quota-warning { + args = below %{user} + } + } } service quota-warning { executable = script /usr/local/bin/quota-warning + user = dovecot unix_listener quota-warning { - user = dovecot - group = dovecot - mode = 0660 + user = dovecot + group = dovecot + mode = 0600 } } -# allow postfix to query quota +# Allow postfix to query quota +# +# ref: https://doc.dovecot.org/main/core/plugins/quota.html#quota-service service quota-status { executable = quota-status -p postfix - inet_listener { - address = 127.0.0.1 + inet_listener quota-status { + listen = 127.0.0.1 port = 65265 } client_limit = 1 } - diff --git a/target/dovecot/90-sieve.conf b/target/dovecot/90-sieve.conf index f388009a..6c99b0e0 100644 --- a/target/dovecot/90-sieve.conf +++ b/target/dovecot/90-sieve.conf @@ -1,111 +1,56 @@ -## -## Settings for the Sieve interpreter -## +# Sieve configuration +# +# Sieve (RFC 5228) is a language for filtering e-mail messages. It is designed +# to be implementable on either a mail client or mail server. It is meant to be +# extensible, simple and independent of access protocol, mail architecture and +# operating system. It is suitable for running on a mail server where users may +# not be allowed to execute arbitrary programs, such as on black box IMAP +# servers, since in its basic form it has no variables, loops or ability to +# shell out to external programs. +# +# ref: http://sieve.info/ +# https://doc.dovecot.org/main/core/plugins/sieve.html +# +# ! Do not forget to enable the Sieve plugin in 15-lda.conf and 20-lmtp.conf +# by adding it to the respective `mail_plugins` settings. -# Do not forget to enable the Sieve plugin in 15-lda.conf and 20-lmtp.conf -# by adding it to the respective mail_plugins= settings. +# For `sieve_script ` see +# https://doc.dovecot.org/main/core/plugins/sieve.html#script-storage-types -plugin { - # The path to the user's main active script. If ManageSieve is used, this the - # location of the symbolic link controlled by ManageSieve. - sieve = ~/.dovecot.sieve - - # The default Sieve script when the user has none. This is a path to a global - # sieve script file, which gets executed ONLY if user's private Sieve script - # doesn't exist. Be sure to pre-compile this script manually using the sievec - # command line tool. - # --> See sieve_before fore executing scripts before the user's personal - # script. - #sieve_default = /var/lib/dovecot/sieve/default.sieve - - # Directory for :personal include scripts for the include extension. This - # is also where the ManageSieve service stores the user's scripts. - sieve_dir = ~/sieve - - # Directory for :global include scripts for the include extension. - #sieve_global_dir = - - # Path to a script file or a directory containing script files that need to be - # executed before the user's script. If the path points to a directory, all - # the Sieve scripts contained therein (with the proper .sieve extension) are - # executed. The order of execution within a directory is determined by the - # file names, using a normal 8bit per-character comparison. Multiple script - # file or directory paths can be specified by appending an increasing number. - sieve_before = /usr/lib/dovecot/sieve-global/before/ - #sieve_before2 = - #sieve_before3 = (etc...) - - # Identical to sieve_before, only the specified scripts are executed after the - # user's script (only when keep is still in effect!). Multiple script file or - # directory paths can be specified by appending an increasing number. - sieve_after = /usr/lib/dovecot/sieve-global/after/ - #sieve_after2 = - #sieve_after2 = (etc...) - - # Which Sieve language extensions are available to users. By default, all - # supported extensions are available, except for deprecated extensions or - # those that are still under development. Some system administrators may want - # to disable certain Sieve extensions or enable those that are not available - # by default. This setting can use '+' and '-' to specify differences relative - # to the default. For example `sieve_extensions = +imapflags' will enable the - # deprecated imapflags extension in addition to all extensions were already - # enabled by default. - #sieve_extensions = +notify +imapflags - sieve_extensions = +notify +imapflags +special-use +vnd.dovecot.pipe +vnd.dovecot.filter - - # Which Sieve language extensions are ONLY available in global scripts. This - # can be used to restrict the use of certain Sieve extensions to administrator - # control, for instance when these extensions can cause security concerns. - # This setting has higher precedence than the `sieve_extensions' setting - # (above), meaning that the extensions enabled with this setting are never - # available to the user's personal script no matter what is specified for the - # `sieve_extensions' setting. The syntax of this setting is similar to the - # `sieve_extensions' setting, with the difference that extensions are - # enabled or disabled for exclusive use in global scripts. Currently, no - # extensions are marked as such by default. - #sieve_global_extensions = - - # The Pigeonhole Sieve interpreter can have plugins of its own. Using this - # setting, the used plugins can be specified. Check the Dovecot wiki - # (wiki2.dovecot.org) or the pigeonhole website - # (http://pigeonhole.dovecot.org) for available plugins. - # The sieve_extprograms plugin is included in this release. - #sieve_plugins = - sieve_plugins = sieve_imapsieve sieve_extprograms - - # The separator that is expected between the :user and :detail - # address parts introduced by the subaddress extension. This may - # also be a sequence of characters (e.g. '--'). The current - # implementation looks for the separator from the left of the - # localpart and uses the first one encountered. The :user part is - # left of the separator and the :detail part is right. This setting - # is also used by Dovecot's LMTP service. - #recipient_delimiter = + - - # The maximum size of a Sieve script. The compiler will refuse to compile any - # script larger than this limit. If set to 0, no limit on the script size is - # enforced. - #sieve_max_script_size = 1M - - # The maximum number of actions that can be performed during a single script - # execution. If set to 0, no limit on the total number of actions is enforced. - #sieve_max_actions = 32 - - # The maximum number of redirect actions that can be performed during a single - # script execution. If set to 0, no redirect actions are allowed. - #sieve_max_redirects = 4 - - # The maximum number of personal Sieve scripts a single user can have. If set - # to 0, no limit on the number of scripts is enforced. - # (Currently only relevant for ManageSieve) - #sieve_quota_max_scripts = 0 - - # The maximum amount of disk storage a single user's scripts may occupy. If - # set to 0, no limit on the used amount of disk storage is enforced. - # (Currently only relevant for ManageSieve) - #sieve_quota_max_storage = 0 - - # Locations of programs that can be called by the sieve_extprograms plugin - sieve_pipe_bin_dir = /usr/lib/dovecot/sieve-pipe - sieve_filter_bin_dir = /usr/lib/dovecot/sieve-filter +# The Sieve language has various extensions +# +# ref: https://doc.dovecot.org/main/core/config/sieve/overview.html#extensions +sieve_extensions { + editheader = no + special-use = yes + vnd.dovecot.pipe = yes + vnd.dovecot.filter = yes } + +# The Pigeonhole Sieve interpreter can have plugins of its own +# +# ref: https://doc.dovecot.org/main/core/plugins/sieve.html#sieve_plugins +# https://doc.dovecot.org/main/core/plugins/imap_sieve.html +# https://doc.dovecot.org/main/core/plugins/sieve_extprograms.html +sieve_plugins { + sieve_imapsieve = yes + sieve_extprograms = yes +} + +# The separator between the :user and :detail address parts. +# +# ref: recipient_delimiter +#recipient_delimiter = + + +# Points to a directory where the plugin looks for programs (shell +# scripts) to execute directly and pipe messages to for the +# vnd.dovecot.pipe extension. +# +# ref: https://doc.dovecot.org/main/core/plugins/sieve_extprograms.html#sieve_pipe_bin_dir +sieve_pipe_bin_dir = "/usr/lib/dovecot/sieve-pipe" + +# Points to a directory where the plugin looks for programs (shell +# scripts) to execute directly and filter messages through for the +# vnd.dovecot.filter extension. +# ref: https://doc.dovecot.org/main/core/plugins/sieve_extprograms.html#sieve_filter_bin_dir +sieve_filter_bin_dir = /usr/lib/dovecot/sieve-filter diff --git a/target/dovecot/auth-master.inc b/target/dovecot/auth-master.inc index daebb392..4924e3e8 100755 --- a/target/dovecot/auth-master.inc +++ b/target/dovecot/auth-master.inc @@ -1,8 +1,13 @@ auth_master_user_separator = * -passdb { - driver = passwd-file - args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/masterdb - master = yes - result_success = continue + +passdb passdb-master { + master = yes + driver = passwd-file + passwd_file_path = /etc/dovecot/masterdb + auth_username_format = %{user} + default_password_scheme = SHA512-CRYPT + result_success = continue + + # Required for LDAP #auth_bind = yes } diff --git a/target/dovecot/auth-passwdfile.inc b/target/dovecot/auth-passwdfile.inc index 38be4e5f..f7c909bd 100644 --- a/target/dovecot/auth-passwdfile.inc +++ b/target/dovecot/auth-passwdfile.inc @@ -1,20 +1,25 @@ # Authentication for passwd-file users. Included from 10-auth.conf. # -# Documentation -# PassDB: https://doc.dovecot.org/configuration_manual/authentication/password_databases_passdb/ -# UserDB: https://doc.dovecot.org/configuration_manual/authentication/user_databases_userdb/ -# -# !!! Attention !!! -# Do not add `scheme=SHA512-CRYPT` to the userdb args. This is not supported. +# ref: https://doc.dovecot.org/main/core/config/auth/databases/passwd_file.html -passdb { - driver = passwd-file - mechanisms = plain login - args = scheme=SHA512-CRYPT username_format=%u /etc/dovecot/userdb +passdb passdb-default { + driver = passwd-file + passwd_file_path = /etc/dovecot/userdb + auth_username_format = %{user} + mechanisms_filter = plain login + default_password_scheme = SHA512-CRYPT } -userdb { - driver = passwd-file - args = username_format=%u /etc/dovecot/userdb - default_fields = uid=docker gid=docker home=/var/mail/%d/%u/home/ +userdb userdb-default { + driver = passwd-file + passwd_file_path = /etc/dovecot/userdb + auth_username_format = %{user} + + # Default field values to use when they're not set for user accounts sourced via `/etc/dovecot/userdb`. + # NOTE: That file is created from `postfix-accounts.cf` + `postfix-virtual.cf` + fields { + uid:default = docker + gid:default = docker + home:default = /var/mail/%{user | domain}/%{user}/home/ + } } diff --git a/target/scripts/helpers/accounts.sh b/target/scripts/helpers/accounts.sh index aa344f37..6307b144 100644 --- a/target/scripts/helpers/accounts.sh +++ b/target/scripts/helpers/accounts.sh @@ -186,7 +186,7 @@ function _add_attribute_dovecot_quota() { IFS=':' read -r -a USER_QUOTA < <(grep -i "${MAIL_ACCOUNT}:" /tmp/docker-mailserver/dovecot-quotas.cf) if [[ ${#USER_QUOTA[@]} -eq 2 ]]; then - USER_ATTRIBUTES="${USER_ATTRIBUTES:+${USER_ATTRIBUTES} }userdb_quota_rule=*:bytes=${USER_QUOTA[1]}" + USER_ATTRIBUTES="${USER_ATTRIBUTES:+${USER_ATTRIBUTES} }userdb_quota_storage_size=${USER_QUOTA[1]}" fi fi diff --git a/target/scripts/helpers/ssl.sh b/target/scripts/helpers/ssl.sh index c7d70317..302fed85 100644 --- a/target/scripts/helpers/ssl.sh +++ b/target/scripts/helpers/ssl.sh @@ -51,8 +51,8 @@ function _setup_ssl() { # Dovecot configuration sedfile -i -r \ - -e "s|^(ssl_key =).*|\1 <${DOVECOT_KEY}|" \ - -e "s|^(ssl_cert =).*|\1 <${DOVECOT_CERT}|" \ + -e "s|^(ssl_server_key_file =).*|\1 ${DOVECOT_KEY}|" \ + -e "s|^(ssl_server_cert_file =).*|\1 ${DOVECOT_CERT}|" \ "${DOVECOT_CONFIG_SSL}" } @@ -79,8 +79,8 @@ function _setup_ssl() { # Conditionally checks for `#`, in the event that internal container state is accidentally persisted, # can be caused by: `docker compose up` run again after a `ctrl+c`, without running `docker compose down` sedfile -i -r \ - -e "s|^#?(ssl_alt_key =).*|\1 <${PRIVATE_KEY_ALT}|" \ - -e "s|^#?(ssl_alt_cert =).*|\1 <${CERT_CHAIN_ALT}|" \ + -e "s|^#?(ssl_server_alt_key_file =).*|\1 ${PRIVATE_KEY_ALT}|" \ + -e "s|^#?(ssl_server_alt_cert_file =).*|\1 ${CERT_CHAIN_ALT}|" \ "${DOVECOT_CONFIG_SSL}" } @@ -257,8 +257,8 @@ function _setup_ssl() { # If the Dovecot settings for alt cert has been enabled (doesn't start with `#`), # but required ENV var is missing, reset to disabled state: sed -i -r \ - -e 's|^(ssl_alt_key =).*|#\1 The plaintext authentication is always allowed (and SSL not required) for connections from localhost, as they’re assumed to be secure anyway. - # > This applies to all connections where the local and the remote IP addresses are equal. - # > Also IP ranges specified by login_trusted_networks setting are assumed to be secure. - # - # no => insecure auth allowed, yes (default) => plaintext auth only allowed over a secure connection (insecure connection acceptable for non-plaintext auth) - local DISABLE_PLAINTEXT_AUTH='no' - # no => disabled, yes => optional (secure connections not required), required (default) => mandatory (only secure connections allowed) - local DOVECOT_SSL_ENABLED='no' - sed -i -r "s|^#?(disable_plaintext_auth =).*|\1 ${DISABLE_PLAINTEXT_AUTH}|" /etc/dovecot/conf.d/10-auth.conf - sed -i -r "s|^(ssl =).*|\1 ${DOVECOT_SSL_ENABLED}|" "${DOVECOT_CONFIG_SSL}" + # These two settings `auth_allow_cleartext` + `ssl` impact if TLS for connections is required, + # which can vary by auth mechanism used and context of the connecting client: + # - https://doc.dovecot.org/2.4.1/core/config/ssl.html#how-to-specify-when-ssl-tls-is-required + # - https://doc.dovecot.org/2.4.1/core/summaries/settings.html#auth_allow_cleartext + # - https://doc.dovecot.org/2.4.1/core/summaries/settings.html#ssl + + # NOTE: Trusted clients (`secured` connections) almost always allow cleartext auth, + # with the exception of some when `ssl=required` as detailed in Dovecot docs: + # https://doc.dovecot.org/2.4.1/core/config/ssl.html#secured-connections + + # Allow cleartext auth (mechanisms that don't protect secrets) without requiring an encrypted connection + sed -i -r "s|^#?(auth_allow_cleartext =).*|\1 yes|" /etc/dovecot/conf.d/10-auth.conf + + # Disable TLS listeners on ports (`ssl=no`), unencrypted traffic only + sed -i -r "s|^(ssl =).*|\1 no|" "${DOVECOT_CONFIG_SSL}" ;; ( 'snakeoil' ) # This is a temporary workaround for testing only, using the insecure snakeoil cert. diff --git a/target/scripts/startup/setup.d/dovecot.sh b/target/scripts/startup/setup.d/dovecot.sh index 31f22c8a..44abde87 100644 --- a/target/scripts/startup/setup.d/dovecot.sh +++ b/target/scripts/startup/setup.d/dovecot.sh @@ -144,36 +144,27 @@ function _setup_dovecot_quota() { # Dovecot quota is disabled when using LDAP or SMTP_ONLY or when explicitly disabled. if [[ ${ACCOUNT_PROVISIONER} != 'FILE' ]] || [[ ${SMTP_ONLY} -eq 1 ]] || [[ ${ENABLE_QUOTAS} -eq 0 ]]; then - # disable dovecot quota in docevot confs if [[ -f /etc/dovecot/conf.d/90-quota.conf ]]; then - mv /etc/dovecot/conf.d/90-quota.conf /etc/dovecot/conf.d/90-quota.conf.disab - sedfile -i \ - "s|mail_plugins = \$mail_plugins quota|mail_plugins = \$mail_plugins|g" \ - /etc/dovecot/conf.d/10-mail.conf - sedfile -i \ - "s|mail_plugins = \$mail_plugins imap_quota|mail_plugins = \$mail_plugins|g" \ - /etc/dovecot/conf.d/20-imap.conf + mv /etc/dovecot/conf.d/90-quota.conf /etc/dovecot/conf.d/90-quota.conf.disab + sedfile -i -E 's|^( *quota =).*|\1 no|g' /etc/dovecot/conf.d/10-mail.conf + sedfile -i -E 's|^( *imap_quota =).*|\1 no|g' /etc/dovecot/conf.d/20-imap.conf fi else if [[ -f /etc/dovecot/conf.d/90-quota.conf.disab ]]; then - mv /etc/dovecot/conf.d/90-quota.conf.disab /etc/dovecot/conf.d/90-quota.conf - sedfile -i \ - "s|mail_plugins = \$mail_plugins|mail_plugins = \$mail_plugins quota|g" \ - /etc/dovecot/conf.d/10-mail.conf - sedfile -i \ - "s|mail_plugins = \$mail_plugins|mail_plugins = \$mail_plugins imap_quota|g" \ - /etc/dovecot/conf.d/20-imap.conf + mv /etc/dovecot/conf.d/90-quota.conf.disab /etc/dovecot/conf.d/90-quota.conf + sedfile -i -E 's|^( *quota =).*|\1 yes|g' /etc/dovecot/conf.d/10-mail.conf + sedfile -i -E 's|^( *imap_quota =).*|\1 yes|g' /etc/dovecot/conf.d/20-imap.conf fi local MESSAGE_SIZE_LIMIT_MB=$((POSTFIX_MESSAGE_SIZE_LIMIT / 1000000)) local MAILBOX_LIMIT_MB=$((POSTFIX_MAILBOX_SIZE_LIMIT / 1000000)) sedfile -i \ - "s|quota_max_mail_size =.*|quota_max_mail_size = ${MESSAGE_SIZE_LIMIT_MB}$([[ ${MESSAGE_SIZE_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")|g" \ + "s|quota_mail_size =.*|quota_mail_size = ${MESSAGE_SIZE_LIMIT_MB}$([[ ${MESSAGE_SIZE_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")|g" \ /etc/dovecot/conf.d/90-quota.conf sedfile -i \ - "s|quota_rule = \*:storage=.*|quota_rule = *:storage=${MAILBOX_LIMIT_MB}$([[ ${MAILBOX_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")|g" \ + "s|quota_storage_size = .*|quota_storage_size = ${MAILBOX_LIMIT_MB}$([[ ${MAILBOX_LIMIT_MB} -eq 0 ]] && echo "" || echo "M")|g" \ /etc/dovecot/conf.d/90-quota.conf if [[ -d /tmp/docker-mailserver ]] && [[ ! -f /tmp/docker-mailserver/dovecot-quotas.cf ]]; then diff --git a/target/scripts/startup/setup.d/security/misc.sh b/target/scripts/startup/setup.d/security/misc.sh index a56fecb5..431930cb 100644 --- a/target/scripts/startup/setup.d/security/misc.sh +++ b/target/scripts/startup/setup.d/security/misc.sh @@ -251,11 +251,8 @@ function _setup_spam_subject() { 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' "Enabling Sieve extension 'editheader'" + sedfile -i -E 's|^( *editheader =).*|\1 yes|g' /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 @@ -297,6 +294,8 @@ EOF function _setup_spam_to_junk() { if [[ ${MOVE_SPAM_TO_JUNK} -eq 1 ]]; then _log 'debug' 'Spam emails will be moved to the Junk folder' + + mkdir -p /usr/lib/dovecot/sieve-global/after/ cat >/usr/lib/dovecot/sieve-global/after/spam_to_junk.sieve << EOF require ["fileinto","special-use"]; diff --git a/target/scripts/startup/setup.d/security/rspamd.sh b/target/scripts/startup/setup.d/security/rspamd.sh index 7651b8ab..ab3ad8fe 100644 --- a/target/scripts/startup/setup.d/security/rspamd.sh +++ b/target/scripts/startup/setup.d/security/rspamd.sh @@ -222,20 +222,26 @@ function __rspamd__setup_learning() { readonly SIEVE_PIPE_BIN_DIR ln -s "$(type -f -P rspamc)" "${SIEVE_PIPE_BIN_DIR}/rspamc" - sedfile -i -E 's|(mail_plugins =.*)|\1 imap_sieve|' /etc/dovecot/conf.d/20-imap.conf - sedfile -i -E '/^}/d' /etc/dovecot/conf.d/90-sieve.conf + sedfile -i -E 's|^( *imap_sieve =).*|\1 yes|g' /etc/dovecot/conf.d/20-imap.conf cat >>/etc/dovecot/conf.d/90-sieve.conf << EOF - # From anywhere to Junk - imapsieve_mailbox1_name = Junk - imapsieve_mailbox1_causes = COPY APPEND - imapsieve_mailbox1_before = file:${SIEVE_PIPE_BIN_DIR}/learn-spam.sieve +mailbox Junk { + sieve_script learn_spam { + cause = append copy + driver = file + name = Learn Spam + path = ${SIEVE_PIPE_BIN_DIR}/learn-spam.sieve + type = before + } +} - # From Junk to Inbox - imapsieve_mailbox2_name = INBOX - imapsieve_mailbox2_from = Junk - imapsieve_mailbox2_causes = COPY APPEND - imapsieve_mailbox2_before = file:${SIEVE_PIPE_BIN_DIR}/learn-ham.sieve +imapsieve_from Junk { + sieve_script learn_ham { + cause = append copy + name = Learn Ham + path = ${SIEVE_PIPE_BIN_DIR}/learn-ham.sieve + type = before + } } EOF