484 lines
11 KiB
Text
484 lines
11 KiB
Text
# THIS FILE IS CONTROLLED BY ANSIBLE - DO NOT CHANGE IN DEPLOYMENT!
|
|
|
|
# dovecot config
|
|
|
|
# Note: debian has some settings in conf.d/* that we cannot override
|
|
# (e.g. we cannot unset passdb pam), so we must disable inclusion of conf.d/*
|
|
# in dovecot.conf
|
|
|
|
|
|
# execution
|
|
mail_uid = mailstore
|
|
mail_gid = mailstore
|
|
mail_privileged_group = mailstore
|
|
default_vsz_limit = 512M
|
|
|
|
|
|
# tls
|
|
ssl = required
|
|
ssl_server {
|
|
cert_file = /etc/dovecot/private/dovecot.pem
|
|
key_file = /etc/dovecot/private/dovecot.key
|
|
}
|
|
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
|
|
|
|
|
|
# mail storage
|
|
mail_driver = maildir
|
|
mail_home = /srv/mailstore/%{user | domain}/%{user | username }/
|
|
mail_path = /srv/mailstore/%{user | domain}/%{user | username }/Maildir
|
|
mail_inbox_path = /srv/mailstore/%{user | domain}/%{user | username }/Maildir
|
|
mailbox_list_layout = fs
|
|
|
|
|
|
# auth
|
|
auth_verbose = yes
|
|
auth_mechanisms {
|
|
plain = yes
|
|
login = yes
|
|
}
|
|
auth_verbose = yes
|
|
auth_default_domain = {{ mailserver.dovecot.auth_default_realm }}
|
|
|
|
|
|
# auth service for postfix
|
|
service auth {
|
|
unix_listener auth-userdb {
|
|
}
|
|
unix_listener /var/spool/postfix/private/auth {
|
|
mode = 0660
|
|
user = postfix
|
|
group = postfix
|
|
}
|
|
}
|
|
service auth-worker {
|
|
}
|
|
|
|
|
|
# users and passwords: in postgresql
|
|
pgsql localhost {
|
|
parameters {
|
|
port = {{ mailserver.postgresql.port }}
|
|
user = {{ mailserver.postgresql.username }}
|
|
password = {{ mailserver.postgresql.password }}
|
|
dbname = {{ mailserver.postgresql.dbname }}
|
|
}
|
|
}
|
|
sql_driver = pgsql
|
|
passdb sql {
|
|
driver = sql
|
|
default_password_scheme = PBKDF2
|
|
query = SELECT \
|
|
users.username as user, \
|
|
domains.name as domain, \
|
|
password, \
|
|
suspend_imap_reason as nologin \
|
|
FROM users JOIN domains ON users.domain_id=domains.id \
|
|
WHERE users.username = '%{user | username}' AND domains.name = '%{user | domain }'
|
|
}
|
|
passdb_default_password_scheme = PBKDF2
|
|
userdb sql {
|
|
query = SELECT \
|
|
'/srv/mailstore/' || domains.name || '/' || users.username || '/Maildir/' as home, \
|
|
'mailstore' as uid, \
|
|
'mailstore' as gid, \
|
|
CONCAT(quota_storage_bytes, 'B') AS quota_storage_size, \
|
|
quota_inbox_messages AS quota_message_count \
|
|
FROM users JOIN domains ON users.domain_id=domains.id \
|
|
WHERE users.username = '%{user | username}' AND domains.name = '%{user | domain}'
|
|
iterate_query = SELECT \
|
|
users.username as username, \
|
|
domains.name as domain \
|
|
FROM users JOIN domains ON users.domain_id=domains.id \
|
|
ORDER BY 2,1
|
|
}
|
|
|
|
|
|
# quota
|
|
mail_plugins {
|
|
quota = yes
|
|
}
|
|
quota_storage_size = 20G
|
|
namespace inbox {
|
|
mailbox Trash {
|
|
quota_storage_extra = 100M
|
|
}
|
|
}
|
|
protocol !indexer-worker {
|
|
mail_vsize_bg_after_count = 100
|
|
}
|
|
protocol imap {
|
|
mail_plugins {
|
|
imap_quota = yes
|
|
}
|
|
}
|
|
quota "user-quota" {
|
|
storage_grace = 200M
|
|
status_success = DUNNO
|
|
status_nouser = DUNNO
|
|
status_overquota = "552 5.2.2 Mailbox is full"
|
|
exceeded_message = "User %{user} is over quota and must reduce the overall mail volume and/or the number of messages in INBOX."
|
|
warning warn-95 {
|
|
quota_storage_percentage = 95
|
|
execute quota-warning {
|
|
args = 95 %{user}
|
|
}
|
|
}
|
|
warning warn-80 {
|
|
quota_storage_percentage = 80
|
|
execute quota-warning {
|
|
args = 80 %{user}
|
|
}
|
|
}
|
|
warning warn-under {
|
|
quota_storage_percentage = 95
|
|
threshold = under
|
|
execute quota-warning {
|
|
args = below %{user}
|
|
}
|
|
}
|
|
}
|
|
service quota-warning {
|
|
executable = script /usr/local/bin/quota-warning.sh
|
|
unix_listener quota-warning {
|
|
user = dovenull
|
|
group = dovenull
|
|
mode = 0660
|
|
}
|
|
}
|
|
service quota-status {
|
|
executable = quota-status -p postfix
|
|
#unix_listener /var/spool/postfix/private/quota-status {
|
|
# user = postfix
|
|
#}
|
|
inet_listener quota-status {
|
|
port = 12480
|
|
}
|
|
client_limit = 1
|
|
}
|
|
# check:
|
|
# doveadm quota get -A
|
|
# echo -e "recipient=USER@DOMAIN\n" | nc -v 127.0.0.1 12480
|
|
|
|
|
|
# namespaces
|
|
namespace inbox {
|
|
type = private
|
|
inbox = yes
|
|
mail_driver = maildir
|
|
separator = /
|
|
mail_path = /srv/mailstore/%{user | domain}/%{user | username}/Maildir
|
|
mailbox_list_layout = fs
|
|
# location = maildir:/srv/mailstore/%%d/%%n/Maildir:LAYOUT=fs:INDEXPVT=~/shared/%%d/%%n/
|
|
subscriptions = yes
|
|
list = yes
|
|
mailbox Drafts {
|
|
special_use = \Drafts
|
|
}
|
|
mailbox Junk {
|
|
auto = subscribe
|
|
special_use = \Junk
|
|
autoexpunge = 180d
|
|
}
|
|
mailbox Trash {
|
|
auto = subscribe
|
|
special_use = \Trash
|
|
autoexpunge = 180d
|
|
}
|
|
mailbox Sent {
|
|
special_use = \Sent
|
|
}
|
|
mailbox "Sent Messages" {
|
|
special_use = \Sent
|
|
}
|
|
}
|
|
namespace shared {
|
|
type = shared
|
|
inbox = no
|
|
mail_driver = maildir
|
|
separator = /
|
|
prefix = shared/$user/
|
|
#prefix = shared/$domain/$username/
|
|
mail_path = /srv/mailstore/%{owner_user | domain}/%{owner_user | username}/Maildir
|
|
#mail_index_path = ~/shared/%{owner_user | domain}/%{owner_user | username}/
|
|
mail_index_private_path = ~/shared/%{owner_user | domain}/%{owner_user | username}/
|
|
mailbox_list_layout = fs
|
|
subscriptions = no
|
|
list = yes
|
|
}
|
|
#namespace roles {
|
|
# type = shared
|
|
# inbox = no
|
|
# mail_driver = maildir
|
|
# separator = /
|
|
# prefix = roles/
|
|
# mail_path = /srv/mailstore/role_specific/roles/Maildir
|
|
# mailbox_list_layout = fs
|
|
# mail_index_private_path = ~/role_specific/roles/
|
|
# subscriptions = no
|
|
# list = yes
|
|
#}
|
|
#namespace virtual {
|
|
# separator = /
|
|
# prefix = virtual/
|
|
# mail_path = virtual:/srv/mailstore/%{user | domain}/%{user | username}/Maildir_virtual
|
|
#}
|
|
|
|
|
|
# imap service
|
|
service imap {
|
|
}
|
|
service imap-login {
|
|
inet_listener imap {
|
|
type = imap
|
|
}
|
|
inet_listener imaps {
|
|
type = imaps
|
|
}
|
|
}
|
|
|
|
|
|
# lmtp service
|
|
service lmtp {
|
|
unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
|
group = postfix
|
|
mode = 0600
|
|
user = postfix
|
|
}
|
|
}
|
|
protocol lmtp {
|
|
postmaster_address = {{ mailserver.dovecot.postmaster_email }}
|
|
mail_plugins {
|
|
quota = yes
|
|
}
|
|
auth_username_format = %{user | username |lower}@%{user | domain | lower}
|
|
}
|
|
|
|
|
|
# acl
|
|
mail_plugins {
|
|
acl = yes
|
|
}
|
|
acl_driver = vfile
|
|
protocol imap {
|
|
mail_plugins {
|
|
imap_acl = yes
|
|
}
|
|
}
|
|
acl_sharing_map {
|
|
dict proxy {
|
|
name = acl
|
|
}
|
|
}
|
|
imap_acl_allow_anyone = yes
|
|
dict_server {
|
|
dict acl {
|
|
driver = sql
|
|
sql_driver = pgsql
|
|
pgsql localhost {
|
|
parameters {
|
|
port = {{ mailserver.postgresql.port }}
|
|
user = {{ mailserver.postgresql.username }}
|
|
password = {{ mailserver.postgresql.password }}
|
|
dbname = {{ mailserver.postgresql.dbname }}
|
|
}
|
|
}
|
|
dict_map shared/shared-boxes/user/$to/$from {
|
|
sql_table = shared_folders
|
|
value_field dummy {
|
|
}
|
|
key_field from_user {
|
|
value = $from
|
|
}
|
|
key_field to_user {
|
|
value = $to
|
|
}
|
|
}
|
|
dict_map shared/shared-user-boxes-rev/$from/$to {
|
|
sql_table = shared_folders
|
|
value_field dummy {
|
|
}
|
|
key_field from_user {
|
|
value = $from
|
|
}
|
|
key_field to_user {
|
|
value = $to
|
|
}
|
|
}
|
|
dict_map shared/shared-boxes/anyone/$from {
|
|
sql_table = shared_folders_anyone
|
|
value_field dummy {
|
|
}
|
|
key_field from_user {
|
|
value = $from
|
|
}
|
|
}
|
|
}
|
|
}
|
|
service dict {
|
|
unix_listener dict {
|
|
mode = 0660
|
|
user = dovecot
|
|
group = mailstore
|
|
}
|
|
}
|
|
# TODO enable in v2.4.2
|
|
#acl_dict_index = yes
|
|
|
|
# debugging:
|
|
# doveadm acl debug -u ACCESSING_USER@DOMAIN shared/SHARING_USER@DOMAIN/FOLDERNAME
|
|
|
|
|
|
# fulltext search
|
|
mail_plugins {
|
|
fts = yes
|
|
fts_flatcurve = yes
|
|
}
|
|
fts_autoindex = yes
|
|
#fts_autoindex_max_recent_msgs = 0
|
|
fts_search_add_missing = yes
|
|
language_filters = normalizer-icu snowball stopwords
|
|
language_tokenizers = generic email-address
|
|
language_tokenizer_generic_algorithm = simple
|
|
# Note: the 'language' settings is set mandatory by dovecot but has totally NO impact on FTS flatcurve module
|
|
language en {
|
|
default = yes
|
|
filters = lowercase snowball english-possessive stopwords
|
|
}
|
|
language de {
|
|
}
|
|
fts flatcurve {
|
|
substring_search = yes
|
|
}
|
|
# cf. /usr/share/doc/dovecot-fts-xapian/README.md.gz
|
|
fts flatcurve {
|
|
driver = flatcurve
|
|
autoindex = yes
|
|
}
|
|
mailbox Trash {
|
|
special_use = \Trash
|
|
fts_autoindex = no
|
|
}
|
|
mailbox Junk {
|
|
special_use = \Junk
|
|
fts_autoindex = no
|
|
}
|
|
fts_header_excludes {
|
|
* = yes
|
|
}
|
|
fts_header_includes {
|
|
From = yes
|
|
To = yes
|
|
Cc = yes
|
|
Bcc = yes
|
|
Subject = yes
|
|
Message-ID = yes
|
|
Date = yes
|
|
}
|
|
|
|
|
|
# sieve plugin
|
|
# Note: we put sieve scripts below /var/lib/dovecot/sieve/ rather than /etc,
|
|
# because dovecot may want to recompile *.svbin and writing under /etc is prohobited
|
|
# by systemd setting ProtectSystem=full
|
|
protocols {
|
|
sieve = yes
|
|
}
|
|
protocol sieve {
|
|
}
|
|
protocol lmtp {
|
|
mail_plugins {
|
|
sieve = yes
|
|
}
|
|
}
|
|
sieve_script personal {
|
|
type = personal
|
|
active_path = /srv/mailstore/%{user | domain}/%{user | username }/.dovecot.sieve
|
|
path = /srv/mailstore/%{user | domain}/%{user | username }/sieve
|
|
}
|
|
sieve_script before {
|
|
type = before
|
|
sieve_script_path = /var/lib/dovecot/sieve/before
|
|
}
|
|
sieve_script after {
|
|
type = after
|
|
sieve_script_path = /var/lib/dovecot/sieve/after
|
|
}
|
|
#sieve_user_log_path = /srv/mailstore/%{user | domain}/%{user | username }/.dovecot.sieve.log
|
|
service managesieve {
|
|
}
|
|
service managesieve-login {
|
|
inet_listener sieve {
|
|
port = 4190
|
|
}
|
|
}
|
|
|
|
|
|
# sieve-extprograms plugin
|
|
sieve_plugins {
|
|
sieve_extprograms = yes
|
|
}
|
|
sieve_global_extensions {
|
|
vnd.dovecot.pipe = yes
|
|
vnd.dovecot.filter = yes
|
|
vnd.dovecot.execute = yes
|
|
vnd.dovecot.debug = yes
|
|
}
|
|
sieve_pipe_bin_dir = /var/lib/dovecot/sieve/pipes
|
|
sieve_execute_bin_dir = /var/lib/dovecot/sieve/pipes
|
|
|
|
|
|
# imap-sieve plugin
|
|
protocol imap {
|
|
mail_plugins {
|
|
imap_sieve = yes
|
|
}
|
|
}
|
|
sieve_plugins {
|
|
sieve_imapsieve = yes
|
|
}
|
|
mailbox Junk {
|
|
sieve_script learn-spam {
|
|
type = before
|
|
cause = copy
|
|
path = /var/lib/dovecot/sieve/pipes/learn-spam.sieve
|
|
}
|
|
}
|
|
imapsieve_from Junk {
|
|
sieve_script learn-ham {
|
|
type = before
|
|
cause = copy
|
|
path = /var/lib/dovecot/sieve/pipes/learn-ham.sieve
|
|
}
|
|
}
|
|
|
|
|
|
# (disabled) service health check
|
|
# cf. https://doc.dovecot.org/main/core/config/health_check.html
|
|
#service health-check {
|
|
# executable = script -p health-check.sh
|
|
# inet_listener health-check {
|
|
# port = 5001
|
|
# }
|
|
#}
|
|
|
|
|
|
#log_debug = category=auth
|
|
#log_debug = category=imap
|
|
#log_debug = category=lmtp
|
|
#log_debug = category=fts
|
|
#log_debug = category=sieve
|
|
#log_debug = category=imapsieve
|
|
#log_debug = category=acl
|
|
#log_debug = category=dict_server
|
|
#log_debug = category=namespace
|
|
#log_debug = category=mail
|
|
|
|
|
|
# More info:
|
|
# doveadm -v service status
|
|
|
|
# See also
|
|
# * https://monospace.games/posts/20250815-dovecot-24.html
|
|
# * https://workaround.org/ispmail-trixie/
|
|
# * https://thomas-leister.de/en/mailserver-migrate-config-to-dovecot-2.4-debian-trixie/
|