listen = *, :: protocols = imap sieve mail_plugins = $mail_plugins quota ssl = required ssl_cert = <{{ mailserver.imap_tls_cert }} ssl_key = <{{ mailserver.imap_tls_key }} ssl_dh = , quota_rule=*:bytes= } passdb { driver = sql args = /etc/dovecot/dovecot-sql.conf # Returns: user=, password= } # Mailboxes mail_location = maildir:~/Maildir # Expanded to maildir:/var/mail/vmail//Maildir mail_uid = vmail mail_gid = vmail first_valid_uid = 10 last_valid_uid = 999999 first_valid_gid = 10 last_valid_gid = 999999 mailbox_list_index = yes namespace inbox { separator = '/' inbox = yes mailbox Drafts { special_use = \Drafts auto = subscribe } mailbox Junk { special_use = \Junk auto = subscribe } mailbox Trash { special_use = \Trash auto = subscribe } mailbox Sent { special_use = \Sent auto = subscribe } } # IMAP protocol imap { mail_plugins = $mail_plugins imap_sieve } service imap-login { inet_listener imap { port = 0 } inet_listener imaps { port = 993 ssl = yes } } # Sieve plugin { sieve = file:~/sieve;active=~/.dovecot.sieve sieve_plugins = sieve_imapsieve sieve_extprograms sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.execute sieve_pipe_bin_dir = /etc/dovecot/sieve-extprograms {% if mailserver.dovecot.sieve_before|d(False) %} sieve_before = /etc/dovecot/sieve-scripts/before.sieve {% endif %} {% if mailserver.dovecot.sieve_default|d(False) %} sieve_default = /etc/dovecot/sieve-scripts/default.sieve {% endif %} {% if mailserver.dovecot.sieve_after|d(False) %} sieve_after = /etc/dovecot/sieve-scripts/after.sieve {% endif %} {% for name, handler in mailserver.dovecot.sieve_mailbox_handlers.items() %} # {{ name }} imapsieve_mailbox{{ loop.index }}_name = {{ handler.name }} imapsieve_mailbox{{ loop.index }}_causes = {{ handler.causes }} {% if handler.from|d(False) %} imapsieve_mailbox{{ loop.index }}_from = {{ handler.from }} {% endif %} {% if handler.before|d(False) %} imapsieve_mailbox{{ loop.index }}_before = /etc/dovecot/sieve-scripts/mailbox_{{ name }}_before.sieve {% endif %} {% if handler.after|d(False) %} imapsieve_mailbox{{ loop.index }}_after = /etc/dovecot/sieve-scripts/mailbox_{{ name }}_after.sieve {% endif %} {% endfor %} } service managesieve-login { inet_listener sieve { port = 4190 } } # Misc service auth { unix_listener auth-userdb { mode = 0777 } # Postfix uses this socket for submission auth unix_listener /var/spool/postfix/private/auth { mode = 0666 user = postfix group = postfix } } service quota-status { executable = quota-status -p postfix # Postfix uses this socket to check quotas on delivery (as check_policy_service) unix_listener /var/spool/postfix/private/policy-quota { mode = 0666 user = postfix group = postfix } client_limit = 1 } # Metrics service stats { unix_listener stats-reader { user = vmail group = vmail mode = 0660 } unix_listener stats-writer { user = vmail group = vmail # 0666 instead of 0660, so postfixadmin can call doveadm pw without errors mode = 0666 } inet_listener http { port = 9900 } } metric auths { filter = event=auth_request_finished } metric auth_successes { filter = event=auth_request_finished AND success=yes } metric imap_commands { filter = event=imap_command_finished group_by = cmd_name tagged_reply_state duration:exponential:1:9:10 } metric sieve_actions { filter = event=sieve_action_finished group_by = action_name } metric mail_deliveries { filter = event=mail_delivery_finished } # Postfix delivers incoming mails via lda (transport "dovecot") lda_mailbox_autocreate = yes protocol lda { mail_plugins = $mail_plugins sieve } # Quota plugin { # Use postfixadmins quota2 table, so used_quota works quota = dict:User quota::proxy::pgsql # Default quota rule, overwritten by userdb quota_rule = *:storage=0 # 0=unlimited quota_grace = 10%% quota_status_success = DUNNO quota_status_nouser = DUNNO quota_status_overquota = "552 5.2.2 Mailbox is full" } service dict { unix_listener dict { mode = 0600 user = vmail } } dict { # proxy::pgsql pgsql = pgsql:/etc/dovecot/dovecot-dict-sql.conf } {% if mailserver.dovecot.debug %} # Debugging auth_verbose = yes auth_debug = yes mail_debug = yes {% endif %} {% macro config_items(obj) %} {% for key, value in obj.items() %} {% if value is mapping %} {{ key }} { {{ config_items(value)|indent(first=true) }} } {% else %} {{ key }} = {{ value }} {% endif %} {% endfor %} {% endmacro %} {{ config_items(mailserver.dovecot.config) }}