diff --git a/ansible/roles/dovecot/tasks/main.yml b/ansible/roles/dovecot/tasks/main.yml index fc6158bc..8e7a92d0 100644 --- a/ansible/roles/dovecot/tasks/main.yml +++ b/ansible/roles/dovecot/tasks/main.yml @@ -98,17 +98,6 @@ tags: - role::dovecot -- name: Set up sieve configuration for dovecot - lineinfile: - path: /etc/dovecot/conf.d/90-sieve.conf - regexp: "sieve_after =" - line: " sieve_after = /etc/dovecot/sieve-after # (ansible managed)" - state: present - notify: - - Reload Dovecot - tags: - - role::dovecot - - name: Create dovecot spam & ham sieve scripts template: src: "{{ item }}.j2" @@ -149,44 +138,16 @@ tags: - role::dovecot -- name: Enable dovecot spamc learning integration - blockinfile: - path: /etc/dovecot/conf.d/90-sieve.conf - insertbefore: "^}$" - content: |2 - # From elsewhere to Junk folder - imapsieve_mailbox1_name = Junk - imapsieve_mailbox1_causes = COPY - imapsieve_mailbox1_before = file:/etc/dovecot/sieve/learn-spam.sieve - - # From Junk folder to elsewhere - imapsieve_mailbox2_name = * - imapsieve_mailbox2_from = Junk - imapsieve_mailbox2_causes = COPY - imapsieve_mailbox2_before = file:/etc/dovecot/sieve/learn-ham.sieve - - sieve_pipe_bin_dir = {{ dovecot_sieve_pipe_bin_dir }} - sieve_global_extensions = +vnd.dovecot.pipe - sieve_plugins = sieve_imapsieve sieve_extprograms - imapsieve_url = sieve://127.0.0.1:4190 - marker: " # {mark} spam & ham autolearning (ansible managed)" - state: present - notify: - - Reload Dovecot - tags: - - role::dovecot - -- name: Template Dovecot LDAP config - template: - src: dovecot-ldap.conf.ext.j2 - dest: /etc/dovecot/dovecot-ldap.conf.ext - group: root - owner: root - mode: "0600" +# BEGIN temporary cleanup task +- name: Kill Dovecot LDAP config + file: + path: /etc/dovecot/dovecot-ldap.conf.ext + state: absent tags: - role::dovecot notify: - Reload Dovecot +# END temporary cleanup task - name: Template Dovecot component configurations template: @@ -194,8 +155,9 @@ dest: "/etc/dovecot/conf.d/{{ item }}" group: root owner: root - mode: "0644" + mode: "0600" loop: + - 10-director.conf - 10-mail.conf - 10-master.conf - 10-auth.conf @@ -203,6 +165,8 @@ - 15-mailboxes.conf - 20-lmtp.conf - 20-imap.conf + - 90-acl.conf + - 90-sieve.conf - auth-ldap.conf.ext tags: - role::dovecot diff --git a/ansible/roles/dovecot/templates/configs/10-auth.conf.j2 b/ansible/roles/dovecot/templates/configs/10-auth.conf.j2 index a06b02b2..905ed127 100644 --- a/ansible/roles/dovecot/templates/configs/10-auth.conf.j2 +++ b/ansible/roles/dovecot/templates/configs/10-auth.conf.j2 @@ -4,15 +4,18 @@ ## Authentication processes ## -# Disable LOGIN command and all other plaintext authentications unless -# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP +#log_debug=category=auth +#auth_debug_passwords = yes + +# Enable LOGIN command and all other plaintext authentications even if +# SSL/TLS is not used (LOGINDISABLED capability). Note that if the remote IP # 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 +# connection is considered secure and plaintext authentication is allowed, +# unless ssl = required. +auth_allow_cleartext = no # Authentication cache size (e.g. 10M). 0 means it's disabled. Note that -# bsdauth and PAM require cache_key to be set for caching to be used. +# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used. #auth_cache_size = 0 # Time to live for cached data. After TTL expires the cached record is no # longer used, *except* if the main database lookup returns internal failure. @@ -32,7 +35,7 @@ disable_plaintext_auth = yes # Default realm/domain to use if none was specified. This is used for both # SASL realms and appending @domain to username in plaintext logins. -#auth_default_realm = +#auth_default_domain = # List of allowed characters in username. If the user-given username contains # a character not listed in here, the login automatically fails. This is just @@ -46,11 +49,10 @@ disable_plaintext_auth = yes # that '#' and '/' characters are translated to '@'. #auth_username_translation = -# Username formatting before it's looked up from databases. You can use -# the standard variables here, eg. %Lu would lowercase the username, %n would -# drop away the domain if it was given, or "%n-AT-%d" would change the '@' into -# "-AT-". This translation is done after auth_username_translation changes. -auth_username_format = %Ln +# Username formatting before it's looked up from databases. +auth_username_format = %{user|lower} +#auth_username_format = %{user|username|lower} + # If you want to allow master users to log in by specifying the master # username within the normal username string (ie. not using SASL mechanism's @@ -62,11 +64,6 @@ auth_username_format = %Ln # Username to use for users logging in with ANONYMOUS SASL mechanism #auth_anonymous_username = anonymous -# Maximum number of dovecot-auth worker processes. They're used to execute -# blocking passdb and userdb queries (eg. MySQL and PAM). They're -# automatically created and destroyed as needed. -#auth_worker_max_count = 30 - # Host name to use in GSSAPI principal names. The default is to use the # name returned by gethostname(). Use "$ALL" (with quotes) to allow all keytab # entries. @@ -78,7 +75,7 @@ auth_username_format = %Ln #auth_krb5_keytab = # Do NTLM and GSS-SPNEGO authentication using Samba's winbind daemon and -# ntlm_auth helper. +# ntlm_auth helper. #auth_use_winbind = no # Path for Samba's ntlm_auth helper binary. @@ -96,10 +93,10 @@ auth_username_format = %Ln #auth_ssl_username_from_cert = no # Space separated list of wanted authentication mechanisms: -# plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp -# gss-spnego -# NOTE: See also disable_plaintext_auth setting. -auth_mechanisms = plain login +# plain login digest-md5 cram-md5 ntlm anonymous gssapi +# gss-spnego xoauth2 oauthbearer +# NOTE: See also auth_allow_cleartext setting. +#auth_mechanisms = plain login ## ## Password and user databases @@ -111,15 +108,16 @@ auth_mechanisms = plain login # allow both system users (/etc/passwd) and virtual users to login without # duplicating the system users into virtual database. # -# +# # # User database specifies where mails are located and what user/group IDs # own them. For single-UID configuration use "static" userdb. # -# +# #!include auth-deny.conf.ext #!include auth-master.conf.ext +#!include auth-oauth2.conf.ext #!include auth-system.conf.ext #!include auth-sql.conf.ext diff --git a/ansible/roles/dovecot/templates/configs/10-director.conf.j2 b/ansible/roles/dovecot/templates/configs/10-director.conf.j2 new file mode 100644 index 00000000..6ec04838 --- /dev/null +++ b/ansible/roles/dovecot/templates/configs/10-director.conf.j2 @@ -0,0 +1,62 @@ +# {{ ansible_managed }} + +## +## Director-specific settings. +## + +# Director can be used by Dovecot proxy to keep a temporary user -> mail server +# mapping. As long as user has simultaneous connections, the user is always +# redirected to the same server. Each proxy server is running its own director +# process, and the directors are communicating the state to each others. +# Directors are mainly useful with NFS-like setups. + +# List of IPs or hostnames to all director servers, including ourself. +# Ports can be specified as ip:port. The default port is the same as +# what director service's inet_listener is using. +#director_servers = + +# List of IPs or hostnames to all backend mail servers. Ranges are allowed +# too, like 10.0.0.10-10.0.0.30. +#director_mail_servers = + +# How long to redirect users to a specific server after it no longer has +# any connections. +#director_user_expire = 15 min + +# How the username is translated before being hashed. Useful values include +# %Ln if user can log in with or without @domain, %Ld if mailboxes are shared +# within domain. +#director_username_hash = %Lu + +# To enable director service, uncomment the modes and assign a port. +service director { + unix_listener login/director { + #mode = 0666 + } + fifo_listener login/proxy-notify { + #mode = 0666 + } + unix_listener director-userdb { + #mode = 0600 + } + inet_listener schweinehund { + #port = + } +} + +# Enable director for the wanted login services by telling them to +# connect to director socket instead of the default login socket: +service imap-login { + #executable = imap-login director +} +service pop3-login { + #executable = pop3-login director +} +service submission-login { + #executable = submission-login director +} + +# Enable director for LMTP proxying: +protocol lmtp { + #auth_socket_path = director-userdb +} diff --git a/ansible/roles/dovecot/templates/configs/10-mail.conf.j2 b/ansible/roles/dovecot/templates/configs/10-mail.conf.j2 index 23f15a1e..45ece66d 100644 --- a/ansible/roles/dovecot/templates/configs/10-mail.conf.j2 +++ b/ansible/roles/dovecot/templates/configs/10-mail.conf.j2 @@ -4,7 +4,7 @@ ## Mailbox locations and namespaces ## -# Location for users' mailboxes. The +# 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 # location. @@ -14,23 +14,28 @@ # 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.: +# %{user} - username +# %{user|username} - user part in user@domain, same as %u if there's no domain +# %{user|domain} - domain part in user@domain, empty if there's no domain +# %{home} - home directory # -# %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 https://doc.dovecot.org/latest/core/settings/variables.html for full list +# of variables. # -# See doc/wiki/Variables.txt for full list. Some examples: +# Example: +# mail_driver = maildir +# mail_path = ~/Maildir +# mail_inbox_path = ~/Maildir/.INBOX # -# 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 -# -# -# -mail_home = /var/vmail/%u -mail_location = maildir:~/mail + +# Debian defaults +# Note that upstream considers mbox deprecated and strongly recommends +# against its use in production environments. See further information +# at +# https://doc.dovecot.org/2.4.0/core/config/mailbox/formats/mbox.html +mail_home = /var/vmail/%{user | username} +mail_driver = Maildir +mail_path = %{home}/mail # If you need to set multiple mailbox locations or want to change default @@ -58,7 +63,8 @@ namespace inbox { # Physical location of the mailbox. This is in same format as # mail_location, which is also the default for it. - #location = + # mail_driver = + # mail_path = # There can be only one INBOX, and this setting defines which namespace # has it. @@ -84,18 +90,20 @@ namespace inbox { } # Example shared namespace configuration -#namespace { +#namespace shared { #type = shared #separator = / # Mailboxes are visible under "shared/user@domain/" - # %%n, %%d and %%u are expanded to the destination user. - #prefix = shared/%%u/ + # $user, $domain and $username are expanded to the destination user. + #prefix = shared/$user/ - # Mail location for other users' mailboxes. Note that %variables and ~/ - # expands to the logged in user's data. %%n, %%d, %%u and %%h expand to the + # Mail location for other users' mailboxes. Note that %{variables} and ~/ + # expands to the logged in user's data. %{owner_user} and %{owner_home} # destination user's data. - #location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u + #mail_driver = maildir + #mail_path = %{owner_home}/Maildir + #mail_index_path = ~/Maildir/shared/%{owner_user} # Use the default namespace for saving subscriptions. #subscriptions = no @@ -108,11 +116,11 @@ namespace inbox { # System user and group used to access mails. If you use multiple, userdb # can override these by returning uid or gid fields. You can use either numbers -# or names. +# or names. mail_uid = {{ dovecot_vmail_uid }} mail_gid = {{ dovecot_vmail_uid }} -# Group to enable temporarily for privileged operations. Currently this is +# Group to enable temporarily for privileged operations. Currently this is # used only with INBOX when either its initial creation or dotlocking fails. # Typically this is set to "mail" to give access to /var/mail. mail_privileged_group = mail @@ -132,7 +140,11 @@ mail_privileged_group = mail # Dictionary for key=value mailbox attributes. This is used for example by # URLAUTH and METADATA extensions. -#mail_attribute_dict = +#mail_attribute { +# dict file { +# path = %{home}/Maildir/dovecot-attributes +# } +#} # A comment or note that is associated with the server. This value is # accessible for authenticated users through the IMAP METADATA server @@ -215,11 +227,20 @@ mail_privileged_group = mail #auth_socket_path = /var/run/dovecot/auth-userdb # Directory where to look up mail plugins. -#mail_plugin_dir = /usr/lib/dovecot/modules +#mail_plugin_dir = /usr/lib/dovecot # 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 = welcome notify +#mail_plugins = +# +# To add plugins, use +#mail_plugins { +# plugin = yes +#} +mail_plugins { + welcome = yes + notify = yes +} ## ## Mailbox handling optimizations @@ -245,7 +266,7 @@ mail_plugins = welcome notify # When IDLE command is running, mailbox is checked once in a while to see if # there are any new mails or other changes. This setting defines the minimum -# time to wait between those checks. +# time to wait between those checks. Dovecot can also use inotify and # kqueue to find out immediately when changes occur. #mailbox_idle_check_interval = 30 secs @@ -324,14 +345,8 @@ protocol !indexer-worker { # in is important to avoid deadlocks if other MTAs/MUAs are using multiple # locking methods as well. Some operating systems don't allow using some of # them simultaneously. -# -# The Debian value for mbox_write_locks differs from upstream Dovecot. It is -# changed to be compliant with Debian Policy (section 11.6) for NFS safety. -# Dovecot: mbox_write_locks = dotlock fcntl -# Debian: mbox_write_locks = fcntl dotlock -# #mbox_read_locks = fcntl -#mbox_write_locks = fcntl dotlock +#mbox_write_locks = dotlock fcntl # Maximum time to wait for lock (all of them) before aborting. #mbox_lock_timeout = 5 mins @@ -387,32 +402,6 @@ protocol !indexer-worker { # filesystems (ext4, xfs). #mdbox_preallocate_space = no -## -## Mail attachments -## - -# sdbox and mdbox support saving mail attachments to external files, which -# also allows single instance storage for them. Other backends don't support -# this for now. - -# Directory root where to store mail attachments. Disabled, if empty. -#mail_attachment_dir = - -# Attachments smaller than this aren't saved externally. It's also possible to -# write a plugin to disable saving specific attachments externally. -#mail_attachment_min_size = 128k - -# Filesystem backend to use for saving attachments: -# posix : No SiS done by Dovecot (but this might help FS's own deduplication) -# sis posix : SiS with immediate byte-by-byte comparison during saving -# sis-queue posix : SiS with delayed comparison and deduplication -#mail_attachment_fs = sis posix - -# Hash format to use in attachment filenames. You can add any text and -# variables: %{md4}, %{md5}, %{sha1}, %{sha256}, %{sha512}, %{size}. -# Variables can be truncated, e.g. %{sha256:80} returns only first 80 bits -#mail_attachment_hash = %{sha1} - # Settings to control adding $HasAttachment or $HasNoAttachment keywords. # By default, all MIME parts with Content-Disposition=attachment, or inlines # with filename parameter are consired attachments. @@ -424,9 +413,11 @@ protocol !indexer-worker { # exclude-inlined - Exclude any Content-Disposition=inline MIME part. #mail_attachment_detection_options = -plugin { - welcome_script = welcome %u - welcome_wait = no +welcome { + execute welcome { + args = %{user} + } + wait = no } service welcome { diff --git a/ansible/roles/dovecot/templates/configs/10-master.conf.j2 b/ansible/roles/dovecot/templates/configs/10-master.conf.j2 index b338eac7..cce24b20 100644 --- a/ansible/roles/dovecot/templates/configs/10-master.conf.j2 +++ b/ansible/roles/dovecot/templates/configs/10-master.conf.j2 @@ -27,14 +27,14 @@ service imap-login { # Number of connections to handle before starting a new process. Typically # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0 - # is faster. - #service_count = 1 + # is faster. + #service_restart_request_count = 1 # Number of processes to always keep waiting for more connections. #process_min_avail = 0 - # If you set service_count=0, you probably need to grow this. - #vsz_limit = $default_vsz_limit + # If you set service_restart_request_count=0, you probably need to grow this. + #vsz_limit = 256M # default } service pop3-login { @@ -51,8 +51,21 @@ service submission-login { inet_listener submission { #port = 587 } + #inet_listener submissions { + #port = 465 + #} } +# unix_listener lmtp { +# #mode = 0666 + # Create inet listener only if you can't use the above UNIX socket + #inet_listener lmtp { + # Avoid making LMTP visible for the entire internet + #listen = 127.0.0.1 + #port = 24 + #} +#} + service lmtp { unix_listener /var/spool/postfix/private/dovecot-lmtp { mode = 0600 @@ -64,7 +77,7 @@ service lmtp { service imap { # Most of the memory goes to mmap()ing files. You may need to increase this # limit if you have huge mailboxes. - #vsz_limit = $default_vsz_limit + #vsz_limit = 256M # default # Max. number of IMAP processes (connections) #process_limit = 1024 @@ -81,6 +94,31 @@ service submission { } service auth { + # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have + # full permissions to this socket are able to get a list of all usernames and + # get the results of everyone's userdb lookups. + # + # The default 0666 mode allows anyone to connect to the socket, but the + # userdb lookups will succeed only if the userdb returns an "uid" field that + # matches the caller process's UID. Also if caller's uid or gid matches the + # socket's uid or gid the lookup succeeds. Anything else causes a failure. + # + # To give the caller full permissions to lookup all users, set the mode to + # something else than 0666 and Dovecot lets the kernel enforce the + # permissions (e.g. 0777 allows everyone full permissions). + #unix_listener auth-userdb { + #mode = 0666 + #user = + #group = + #} + + # Postfix smtp-auth + #unix_listener /var/spool/postfix/private/auth { + # mode = 0666 + #} + + # Auth process is run as this user. + #user = $SET:default_internal_user unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix @@ -91,7 +129,7 @@ service auth { service auth-worker { # Auth worker process is run as root by default, so that it can access # /etc/shadow. If this isn't necessary, the user should be changed to - # $default_internal_user. + # $SET:default_internal_user. #user = root } diff --git a/ansible/roles/dovecot/templates/configs/10-ssl.conf.j2 b/ansible/roles/dovecot/templates/configs/10-ssl.conf.j2 index 1e5fae41..046db60b 100644 --- a/ansible/roles/dovecot/templates/configs/10-ssl.conf.j2 +++ b/ansible/roles/dovecot/templates/configs/10-ssl.conf.j2 @@ -4,57 +4,52 @@ ## SSL settings ## -# SSL/TLS support: yes, no, required. +# SSL/TLS support: yes, no, required. ssl = yes -# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before -# dropping root privileges, so keep the key file unreadable by anyone but -# root. Included doc/mkcert.sh can be used to easily generate self-signed -# certificate, just make sure to update the domains in dovecot-openssl.cnf -ssl_cert = ) instead of full path # syntax. # -# The list is space-separated. -#lmtp_client_workarounds = +#lmtp_client_workarounds { +# whitespace-before-path = yes +#} protocol lmtp { + # This strips the domain name before delivery, since the default + # userdb in Debian is /etc/passwd, which doesn't include domain + # names in the user. If you're using a different userdb backend + # that does include domain names, you may wish to remove this. See + # https://doc.dovecot.org/2.4.0/howto/lmtp/exim.html and + # https://doc.dovecot.org/2.4.0/core/summaries/settings.html#auth_username_format + auth_username_format = %{user | username} + # Space separated list of plugins to load (default is global mail_plugins). - mail_plugins = $mail_plugins sieve + mail_plugins { + sieve = yes + } } diff --git a/ansible/roles/dovecot/templates/configs/90-acl.conf.j2 b/ansible/roles/dovecot/templates/configs/90-acl.conf.j2 new file mode 100644 index 00000000..58bf9057 --- /dev/null +++ b/ansible/roles/dovecot/templates/configs/90-acl.conf.j2 @@ -0,0 +1,29 @@ +# {{ ansible_managed }} + +## +## Mailbox access control lists. +## + +# vfile backend reads ACLs from "dovecot-acl" file from mail directory. +# You can also optionally give a global ACL directory path where ACLs are +# applied to all users' mailboxes. The global ACL directory contains +# one file for each mailbox, eg. INBOX or sub.mailbox. cache_secs parameter +# specifies how many seconds to wait between stat()ing dovecot-acl file +# to see if it changed. +#acl_driver = vfile +## Deprecated ACL global path +#acl_global_path = /etc/dovecot/global-acls +#acl_cache_ttl = 5m + +## New inline ACLs +#mailbox INBOX { +# acl user=testuser { +# rights = lri +# } +#} + +# To let users LIST mailboxes shared by other users, Dovecot needs a +# shared mailbox dictionary. For example: +#plugin { + #acl_shared_dict = file:/var/lib/dovecot/shared-mailboxes +#} diff --git a/ansible/roles/dovecot/templates/configs/90-sieve.conf.j2 b/ansible/roles/dovecot/templates/configs/90-sieve.conf.j2 new file mode 100644 index 00000000..61a420c8 --- /dev/null +++ b/ansible/roles/dovecot/templates/configs/90-sieve.conf.j2 @@ -0,0 +1,123 @@ +# {{ ansible_managed }} + +## +## Settings for the Sieve interpreter +## + +# Do not forget to enable the Sieve plugin in 15-lda.conf and 20-lmtp.conf +# by adding it to the respective mail_plugins { sieve = yes } settings. + +# See https://doc.dovecot.org/latest/core/plugins/sieve.html + +# Personal sieve script location +#sieve_script personal { +# driver = file +# path = ~/sieve +# active_path = ~/.dovecot.sieve +#} + +# Default sieve script location +#sieve_script default { +# type = default +# name = default +# driver = file +# path = /etc/dovecot/sieve/default/ +#} + + +# 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 'yes' and 'no' to specify differences relative +# to the default. For example `imapflags = yes' will enable the +# deprecated imapflags extension in addition to all extensions were already +# enabled by default. +#sieve_extensions { +# mboxmetadata = yes +# vnd.dovecot.debug = yes +#} + +# 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 { + vnd.dovecot.execute = yes + vnd.dovecot.pipe = yes +} + +# The Pigeonhole Sieve interpreter can have plugins of its own. Using this +# setting, the used plugins can be specified. Check the Dovecot documentation +# https://doc.dovecot.org/latest/core/plugins/sieve.html + +sieve_plugins { + sieve_imapsieve = yes + sieve_extprograms = yes +} + +#sieve_pipe_bin_dir = /usr/share/dovecot-pigeonhole/sieve +#sieve_execute_bin_dir = /usr/share/dovecot-pigeonhole/sieve +imapsieve_url = sieve://127.0.0.1:4190 + +# 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_script_count = 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_storage_size = 0 + +mailbox Junk { + # From elsewhere to Spam folder + sieve_script report-spam { + type = before + cause = copy + path = /etc/dovecot/sieve/learn-spam.sieve + } +} + +## From Spam folder to elsewhere +imapsieve_from Junk { + sieve_script report-ham { + type = before + cause = copy + path = /etc/dovecot/sieve/learn-ham.sieve + } +} + +# After any custom scripts +sieve_script default-after { + type = after + path = /etc/dovecot/sieve-after/ +} diff --git a/ansible/roles/dovecot/templates/configs/auth-ldap.conf.ext.j2 b/ansible/roles/dovecot/templates/configs/auth-ldap.conf.ext.j2 index 2ff06cf9..99f333dd 100644 --- a/ansible/roles/dovecot/templates/configs/auth-ldap.conf.ext.j2 +++ b/ansible/roles/dovecot/templates/configs/auth-ldap.conf.ext.j2 @@ -2,20 +2,98 @@ # Authentication for LDAP users. Included from 10-auth.conf. # -# +# -passdb { - driver = ldap +## See - # Path for LDAP configuration file, see example-config/dovecot-ldap.conf.ext - args = /etc/dovecot/dovecot-ldap.conf.ext -} +#ldap_uris = ldap://localhost +#ldap_auth_dn = cn=admin +#ldap_auth_dn_password = supersecret + +#passdb ldap { +# ldap_filter = (&(objectClass=posixAccount)(uid=%{user})) +# ldap_bind = no +# fields { + # user=%{ldap:uid} + # password=%{ldap:userPassword} + # userdb_home=%{ldap:homeDirectory} + # userdb_uid=%{ldap:uidNumber} + # userdb_gid=%{ldap:gidNumber} +# } +#} +# "prefetch" user database means that the passdb already provided the +# needed information and there's no need to do a separate userdb lookup. +# +#userdb prefetch { +#} +#userdb ldap { +# ldap_filter = (&(objectClass=posixAccount)(uid=%{user})) + +# Default fields can be used to specify defaults that LDAP may override +# fields { +# home=/home/virtual/%{user} +# } +#} +# If you don't have any user-specific settings, you can avoid the userdb LDAP +# lookup by using userdb static instead of userdb ldap, for example: +# +#userdb static { + #fields { + # uid = vmail + # gid = vmail + # home = /var/vmail/%{user} + #} +#} + +# This file is opened as root, so it should be owned by root and mode 0600. +# +ldap_uris = {{ dovecot_ldap_host }} + +# Distinguished Name - the username used to login to the LDAP server. +# Leave it commented out to bind anonymously (useful with auth_bind=yes). +ldap_auth_dn = {{ dovecot_ldap_user }} -userdb { - driver = prefetch +# Password for LDAP server, if dn is specified. +ldap_auth_dn_password = {{ dovecot_ldap_password }} + +# LDAP protocol version to use. Likely 2 or 3. +ldap_version = 3 + +# LDAP base. %variables can be used here. +# For example: dc=mail, dc=example, dc=org +ldap_base = cn=users,cn=accounts,dc=box,dc=pydis,dc=wtf + +# User attributes are given in LDAP-name=dovecot-internal-name list. The +# internal names are: +# uid - System UID +# gid - System GID +# home - Home directory +# mail - Mail location +# +# There are also other special fields which can be returned, see +# http://wiki2.dovecot.org/UserDatabase/ExtraFields + +passdb ldap { + fields { + user = %{ldap:uid} + sieve = %{home}/main.sieve + sieve_user_log_path = %{home}/sieve.log + } + bind = yes + + filter = (&(objectClass=posixAccount)(uid=%{user | username})) + driver = ldap + ldap_connection_group = passdb } -userdb { +userdb ldap { + fields { + user = %{ldap:uid} + uid = %{ldap:uidNumber} + sieve = %{home}/main.sieve + sieve_user_log_path = %{home}/sieve.log + } + filter = (&(objectClass=posixAccount)(uid=%{user | username})) driver = ldap - args = /etc/dovecot/dovecot-ldap.conf.ext + ldap_connection_group = userdb } diff --git a/ansible/roles/dovecot/templates/dovecot-ldap.conf.ext.j2 b/ansible/roles/dovecot/templates/dovecot-ldap.conf.ext.j2 deleted file mode 100644 index a562bf43..00000000 --- a/ansible/roles/dovecot/templates/dovecot-ldap.conf.ext.j2 +++ /dev/null @@ -1,68 +0,0 @@ -# {{ ansible_managed }} - -# This file is commonly accessed via passdb {} or userdb {} section in -# conf.d/auth-ldap.conf.ext - -# This file is opened as root, so it should be owned by root and mode 0600. -# -uris = {{ dovecot_ldap_host }} - -# Distinguished Name - the username used to login to the LDAP server. -# Leave it commented out to bind anonymously (useful with auth_bind=yes). -dn = {{ dovecot_ldap_user }} - -# Password for LDAP server, if dn is specified. -dnpass = {{ dovecot_ldap_password }} - -# TLS options, currently supported only with OpenLDAP: -tls_ca_cert_file = {{ dovecot_ldap_tls_ca }} - -# Use authentication binding for verifying password's validity. This works by -# logging into LDAP server using the username and password given by client. -# The pass_filter is used to find the DN for the user. Note that the pass_attrs -# is still used, only the password field is ignored in it. Before doing any -# search, the binding is switched back to the default DN. -auth_bind = yes - -# If authentication binding is used, you can save one LDAP request per login -# if users' DN can be specified with a common template. The template can use -# the standard %variables (see user_filter). Note that you can't -# use any pass_attrs if you use this setting. -# -# If you use this setting, it's a good idea to use a different -# dovecot-ldap.conf.ext for userdb (it can even be a symlink, just as long as -# the filename is different in userdb's args). That way one connection is used -# only for LDAP binds and another connection is used for user lookups. -# Otherwise the binding is changed to the default DN before each user lookup. -# -# For example: -# auth_bind_userdn = cn=%u,ou=people,o=org -# -auth_bind_userdn = uid=%u,cn=users,cn=accounts,dc=box,dc=pydis,dc=wtf - -# LDAP protocol version to use. Likely 2 or 3. -ldap_version = 3 - -# LDAP base. %variables can be used here. -# For example: dc=mail, dc=example, dc=org -base = cn=users,cn=accounts,dc=box,dc=pydis,dc=wtf - -# User attributes are given in LDAP-name=dovecot-internal-name list. The -# internal names are: -# uid - System UID -# gid - System GID -# home - Home directory -# mail - Mail location -# -# There are also other special fields which can be returned, see -# http://wiki2.dovecot.org/UserDatabase/ExtraFields -user_attrs = uidNumber=uid, sieve=~/main.sieve, sieve_user_log=~/sieve.log - -# Filter for user lookup. Some variables can be used (see -# http://wiki2.dovecot.org/Variables for full list): -# %u - username -# %n - user part in user@domain, same as %u if there's no domain -# %d - domain part in user@domain, empty if user there's no domain -user_filter = (&(objectClass=posixAccount)(uid=%u)) - -pass_filter = (&(objectClass=posixAccount)(uid=%u)) diff --git a/ansible/roles/dovecot/templates/dovecot.conf.j2 b/ansible/roles/dovecot/templates/dovecot.conf.j2 index 3584a859..5fa605f0 100644 --- a/ansible/roles/dovecot/templates/dovecot.conf.j2 +++ b/ansible/roles/dovecot/templates/dovecot.conf.j2 @@ -2,22 +2,28 @@ ## Dovecot configuration file +# If you're in a hurry, see https://doc.dovecot.org/latest/core/config/guides/quick.html + +dovecot_config_version = "2.4.0" +dovecot_storage_version = "2.4.0" + # "doveconf -n" command gives a clean output of the changed settings. Use it # instead of copy&pasting files when posting to the Dovecot mailing list. -# Most (but not all) settings can be overridden by different protocols and/or -# source/destination IPs by placing the settings inside sections, for example: -# protocol imap { }, local 127.0.0.1 { }, remote 10.0.0.0/8 { } +# '#' character and everything after it is treated as comments. Extra spaces +# and tabs are ignored. If you want to use either of these explicitly, put the +# value inside quotes, eg.: key = "# char and trailing whitespace " # Default values are shown for each setting, it's not required to uncomment # those. These are exceptions to this though: No sections (e.g. namespace {}) # or plugin settings are added by default, they're listed only as examples. # Paths are also just examples with the real defaults being based on configure -# options. The paths listed here are for configure --prefix=/usr -# --sysconfdir=/etc --localstatedir=/var +# options. The paths listed here are for configure --prefix=/usr/local +# --sysconfdir=/usr/local/etc --localstatedir=/var -# Enable installed protocols -!include_try /usr/share/dovecot/protocols.d/*.protocol +# Protocols we want to be serving. +protocols = imap lmtp sieve +# !include_try /usr/share/dovecot/protocols.d/*.protocol # A comma separated list of IPs or hosts where to listen in for connections. # "*" listens in all IPv4 interfaces, "::" listens in all IPv6 interfaces. @@ -40,12 +46,10 @@ login_greeting = Schweinehund ready. # Space separated list of trusted network ranges. Connections from these # IPs are allowed to override their IP addresses and ports (for logging and # for authentication checks). disable_plaintext_auth is also ignored for -# these networks. Typically you'd specify your IMAP proxy servers here. +# these networks, unless ssl=required. +# Typically you'd specify your IMAP proxy servers here. #login_trusted_networks = -# Space separated list of login access check sockets (e.g. tcpwrap) -#login_access_sockets = - # With proxy_maybe=yes if proxy destination matches any of these IPs, don't do # proxying. This isn't necessary normally, but may be useful if the destination # IP is e.g. a load balancer's IP. @@ -54,7 +58,7 @@ login_greeting = Schweinehund ready. # Show more verbose process titles (in ps). Currently shows user name and # IP address. Useful for seeing who are actually using the IMAP processes # (eg. shared mailboxes or if same uid is used for multiple accounts). -#verbose_proctitle = no +#verbose_proctitle = yes # Should all processes be killed when Dovecot master process shuts down. # Setting this to "no" means that Dovecot can be upgraded without @@ -71,21 +75,9 @@ login_greeting = Schweinehund ready. # Space separated list of environment variables that are preserved on Dovecot # startup and passed down to all of its child processes. You can also give # key=value pairs to always set specific settings. -#import_environment = TZ - -## -## Dictionary server settings -## - -# Dictionary can be used to store key=value lists. This is used by several -# plugins. The dictionary can be accessed either directly or though a -# dictionary server. The following dict block maps dictionary names to URIs -# when the server is used. These can then be referenced using URIs in format -# "proxy::". - -dict { - #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext -} +#import_environment { +# TZ=%{env:TZ} +#} # Most of the actual configuration gets included below. The filenames are # first sorted by their ASCII value and parsed in that order. The 00-prefixes