chore: adjust Dovecot configuration

Signed-off-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com>
This commit is contained in:
Georg Lauterbach 2026-03-28 20:37:29 +01:00
parent 00e133ca4f
commit 1f9435b03c
No known key found for this signature in database
19 changed files with 291 additions and 266 deletions

View File

@ -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 = </certs/ecprivkey.pem
mail_crypt_global_public_key = </certs/ecpubkey.pem
mail_crypt_global_private_key = /certs/ecprivkey.pem
mail_crypt_global_public_key = /certs/ecpubkey.pem
mail_crypt_save_version = 2
}
```

View File

@ -791,7 +791,7 @@ Add this to `docker-data/dms/config/dovecot.cf`:
```cf
ssl = yes
disable_plaintext_auth=no
auth_allow_cleartext = yes
```
These options in conjunction mean:

View File

@ -55,8 +55,8 @@ function _quota_show_for() {
[[ ${ENABLE_QUOTAS} -ne 1 ]] && return 0
local QUOTA_INFO
# Matches a line where the 3rd column is `type='STORAGE'` - returning the next three column values:
IFS=' ' read -r -a QUOTA_INFO <<< "$(doveadm quota get -u "${MAIL_ACCOUNT}" | tail +2 | awk '{ if ($3 == "STORAGE") { print $4" "$5" "$6 } }')"
# Matches a line where the 2nd column is `STORAGE` - returning the next three column values
IFS=' ' read -r -a QUOTA_INFO <<< "$(doveadm quota get -u "${MAIL_ACCOUNT}" | tail +2 | awk '{ if ($2 == "STORAGE") { print $3" "$4" "$5 } }')"
local CURRENT_SIZE SIZE_LIMIT PERCENT_USED
# Format the extracted quota storage columns:

View File

@ -7,7 +7,7 @@
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
# See also ssl=required setting.
#disable_plaintext_auth = yes
#auth_allow_cleartext = no
# Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used.
@ -96,7 +96,7 @@
# Space separated list of wanted authentication mechanisms:
# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
# gss-spnego
# NOTE: See also disable_plaintext_auth setting.
# NOTE: See also auth_allow_cleartext setting.
auth_mechanisms = plain login
##

View File

@ -41,17 +41,11 @@ auth_verbose_passwords = sha1:6
# isn't finding your mails.
#mail_debug = no
# Show protocol level SSL errors.
verbose_ssl = no
# mail_log plugin provides more event logging for mail processes.
plugin {
# Events to log. Also available: flag_change append
#mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
# Available fields: uid, box, msgid, from, subject, size, vsize, flags
# size and vsize are available only for expunge and copy events.
#mail_log_fields = uid box msgid size
}
# # Show more event logging for mail processes.
#mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
# Available fields: uid, box, msgid, from, subject, size, vsize, flags
# size and vsize are available only for expunge and copy events.
#mail_log_fields = uid box msgid size
##
## Log formatting.

View File

@ -2,6 +2,7 @@
## Mailbox locations and namespaces
##
# TODO The following comment block probably needs further refinements
# Location for users' mailboxes. The default is empty, which means that Dovecot
# tries to find the mailboxes automatically. This won't work if the user
# doesn't yet have any mail, so you should explicitly tell Dovecot the full
@ -10,25 +11,13 @@
# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)
# isn't enough. You'll also need to tell Dovecot where the other mailboxes are
# kept. This is called the "root mail directory", and it must be the first
# path given in the mail_location setting.
#
# There are a few special variables you can use, eg.:
#
# %u - username
# %n - user part in user@domain, same as %u if there's no domain
# %d - domain part in user@domain, empty if there's no domain
# %h - home directory
#
# See doc/wiki/Variables.txt for full list. Some examples:
#
# mail_location = maildir:~/Maildir
# mail_location = mbox:~/mail:INBOX=/var/mail/%u
# mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# <doc/wiki/MailLocation.txt>
#
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

View File

@ -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 = </etc/ssl/certs/ssl-cert-snakeoil.pem
ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key
ssl_server_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
ssl_server_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
# Fallback/Hybrid cert support. docker-mailserver will enable these when using ENV vars `SSL_ALT_CERT_PATH` and `SSL_ALT_KEY_PATH`.
#ssl_alt_cert = </path/to/alternative/cert.pem
#ssl_alt_key = </path/to/alternative/key.pem
#ssl_server_alt_cert_file = /path/to/alternative/cert.pem
#ssl_server_alt_key_file = /path/to/alternative/key.pem
# If key file is password protected, give the password here. Alternatively
# give it when starting dovecot with -p parameter. Since this file is often
# world-readable, you may want to place this setting instead to a different
# root owned 0600 file by using ssl_key_password = <path.
# root owned 0600 file by using ssl_key_password = path.
#ssl_key_password =
# PEM encoded trusted certificate authority. Set this only if you intend to use
# ssl_verify_client_cert=yes. The file should contain the CA certificate(s)
# followed by the matching CRL(s). (e.g. ssl_ca = </etc/ssl/certs/ca.pem)
# followed by the matching CRL(s). (e.g. ssl_ca = /etc/ssl/certs/ca.pem)
#ssl_ca =
# Require that CRL check succeeds for client certificates.
@ -48,7 +48,7 @@ ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key
# SSL DH parameters
# Since v2.3.3+ Diffie-Hellman parameters have been made optional, and you are encouraged to disable non-ECC DH algorithms completely.
# `docker-mailserver` is configured to use the recommended pre-defined 4096-bit DHE Group at https://github.com/internetstandards/dhe_groups
ssl_dh = </etc/dovecot/dh.pem
ssl_server_dh_file = /etc/dovecot/dh.pem
# Minimum SSL protocol version to use. Potentially recognized values are SSLv3,
# TLSv1, TLSv1.1, and TLSv1.2, depending on the OpenSSL version used.
@ -57,8 +57,8 @@ ssl_min_protocol = TLSv1.2
# SSL ciphers to use
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
# Prefer the server's order of ciphers over client's.
ssl_prefer_server_ciphers = yes
# ref: https://doc.dovecot.org/main/core/summaries/settings.html#ssl_server_prefer_ciphers
ssl_server_prefer_ciphers = server
# SSL crypto device to use, for valid values run "openssl engine"
#ssl_crypto_device =

View File

@ -1,4 +1,7 @@
protocol imap {
# allow IMAP clients to ask quota usage
mail_plugins = $mail_plugins imap_quota
# allow IMAP clients to ask quota usage
mail_plugins {
imap_quota = yes
imap_sieve = no
}
}

View File

@ -15,5 +15,7 @@
protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins).
mail_plugins = $mail_plugins sieve
mail_plugins {
sieve = yes
}
}

View File

@ -1,50 +1,89 @@
plugin {
# debug quota using `doveadm quota get -u user@domain`
# recompute quota using `doveadm quota recalc -u user@domain`
# Quota configuration
#
# ref: https://doc.dovecot.org/main/core/plugins/quota.html
#
# ## Commands
#
# - debug quota: doveadm quota get -u <USER>@<DOMAIN>
# - recompute quota: doveadm quota recalc -u <USER>@<DOMAIN>
# Track the current quota usage in Dovecots 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
}

View File

@ -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 <TYPE>` 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

View File

@ -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
}

View File

@ -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/
}
}

View File

@ -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

View File

@ -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 </path/to/alternative/key.pem|' \
-e 's|^(ssl_alt_cert =).*|#\1 </path/to/alternative/cert.pem|' \
-e 's|^(ssl_server_alt_key_file =).*|#\1 /path/to/alternative/key.pem|' \
-e 's|^(ssl_server_alt_cert_file =).*|#\1 /path/to/alternative/cert.pem|' \
"${DOVECOT_CONFIG_SSL}"
fi
@ -353,18 +353,21 @@ function _setup_ssl() {
-e '/smtpd_tls_auth_only/s|yes|no|' \
"${POSTFIX_CONFIG_MASTER}"
# Dovecot configuration:
# https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/
# > The plaintext authentication is always allowed (and SSL not required) for connections from localhost, as theyre 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.

View File

@ -51,8 +51,8 @@ function _register_functions() {
_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'
_register_setup_function '_setup_spam_to_junk'
fi
case "${ACCOUNT_PROVISIONER}" in

View File

@ -61,9 +61,11 @@ function _setup_dovecot() {
( 'sdbox' | 'mdbox' )
_log 'trace' "Dovecot ${DOVECOT_MAILBOX_FORMAT} format configured"
sedfile -i -E "s|^(mail_home =).*|\1 /var/mail/%d/%n|" /etc/dovecot/conf.d/10-mail.conf
sedfile -i -E \
"s|^(mail_location =).*|\1 ${DOVECOT_MAILBOX_FORMAT}:/var/mail/%d/%n|" \
's|^(mail_home =).*|\1 /var/mail/%{user | domain}/%{user | username}|' \
/etc/dovecot/conf.d/10-mail.conf
sedfile -i -E \
"s|^(mail_driver =).*|\1 ${DOVECOT_MAILBOX_FORMAT}|" \
/etc/dovecot/conf.d/10-mail.conf
_log 'trace' 'Enabling cron job for dbox purge'
@ -126,12 +128,26 @@ function _setup_dovecot_sieve() {
/tmp/docker-mailserver/before.dovecot.sieve \
/usr/lib/dovecot/sieve-global/before/50-before.dovecot.sieve
sievec /usr/lib/dovecot/sieve-global/before/50-before.dovecot.sieve
cat >>/etc/dovecot/conf.d/90-sieve.conf <<"EOF"
sieve_script global_before {
type = before
path = /usr/lib/dovecot/sieve-global/before/50-before.dovecot.sieve
}
EOF
fi
if [[ -f /tmp/docker-mailserver/after.dovecot.sieve ]]; then
cp \
/tmp/docker-mailserver/after.dovecot.sieve \
/usr/lib/dovecot/sieve-global/after/50-after.dovecot.sieve
sievec /usr/lib/dovecot/sieve-global/after/50-after.dovecot.sieve
cat >>/etc/dovecot/conf.d/90-sieve.conf <<"EOF"
sieve_script global_after {
type = after
path = /usr/lib/dovecot/sieve-global/before/50-after.dovecot.sieve
}
EOF
fi
chown dovecot:root -R /usr/lib/dovecot/sieve-*
@ -144,36 +160,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

View File

@ -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
@ -290,6 +287,14 @@ EOF
sievec "${DOVECOT_SIEVE_GLOBAL_BEFORE_DIR}/${DOVECOT_SIEVE_FILE}.sieve"
chown dovecot:root "${DOVECOT_SIEVE_GLOBAL_BEFORE_DIR}/${DOVECOT_SIEVE_FILE}."{sieve,svbin}
cat >>/etc/dovecot/conf.d/90-sieve.conf <<EOF
sieve_script global_before {
type = before
path = ${DOVECOT_SIEVE_GLOBAL_BEFORE_DIR}/${DOVECOT_SIEVE_FILE}.sieve
}
EOF
fi
}
@ -298,7 +303,7 @@ 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
cat >/usr/lib/dovecot/sieve-global/after/70-spam_to_junk.sieve << EOF
require ["fileinto","special-use"];
if anyof (header :contains "X-Spam-Flag" "YES",
@ -306,8 +311,17 @@ if anyof (header :contains "X-Spam-Flag" "YES",
fileinto :specialuse "\\\\Junk" "Junk";
}
EOF
sievec /usr/lib/dovecot/sieve-global/after/spam_to_junk.sieve
chown dovecot:root /usr/lib/dovecot/sieve-global/after/spam_to_junk.{sieve,svbin}
sievec /usr/lib/dovecot/sieve-global/after/70-spam_to_junk.sieve
chown dovecot:root /usr/lib/dovecot/sieve-global/after/70-spam_to_junk.{sieve,svbin}
cat >>/etc/dovecot/conf.d/90-sieve.conf <<"EOF"
# Moves e-mails marked with spam headers into Junk
sieve_script spam_to_junk {
type = after
path = /usr/lib/dovecot/sieve-global/after/70-spam_to_junk.sieve
}
EOF
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 0 ]]; then
_log 'warn' "'SPAMASSASSIN_SPAM_TO_INBOX=0' but it is required to be 1 for 'MOVE_SPAM_TO_JUNK=1' to work"
@ -323,7 +337,7 @@ function _setup_spam_mark_as_read() {
mkdir -p /usr/lib/dovecot/sieve-global/after/
# Header support: `X-Spam-Flag` (SpamAssassin), `X-Spam` (Rspamd)
cat >/usr/lib/dovecot/sieve-global/after/spam_mark_as_read.sieve << EOF
cat >/usr/lib/dovecot/sieve-global/after/60-spam_mark_as_read.sieve << EOF
require ["mailbox","imap4flags"];
if anyof (header :contains "X-Spam-Flag" "YES",
@ -331,9 +345,18 @@ if anyof (header :contains "X-Spam-Flag" "YES",
setflag "\\\\Seen";
}
EOF
sievec /usr/lib/dovecot/sieve-global/after/spam_mark_as_read.sieve
sievec /usr/lib/dovecot/sieve-global/after/60-spam_mark_as_read.sieve
chown dovecot:root /usr/lib/dovecot/sieve-global/after/spam_mark_as_read.{sieve,svbin}
cat >>/etc/dovecot/conf.d/90-sieve.conf <<"EOF"
# Moves e-mails marked with spam headers into Junk
sieve_script spam_mark_as_read {
type = after
path = /usr/lib/dovecot/sieve-global/after/60-spam_mark_as_read.sieve
}
EOF
if [[ ${ENABLE_SPAMASSASSIN} -eq 1 ]] && [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 0 ]]; then
_log 'warn' "'SPAMASSASSIN_SPAM_TO_INBOX=0' but it is required to be 1 for 'MARK_SPAM_AS_READ=1' to work"
fi

View File

@ -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