diff --git a/README.md b/README.md index 21c6004a09bfed63fd0f506e8a379ee68c1d72ae..9763192bc070e4dcd6393f4d394da25e6f8eb9a8 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,12 @@ auth_mechanisms: ["plain", "login"] # Array of users if dovecot should handle users in a db. Not usable if you enable ldap. # Each user is a dict, for options see *userdict* below user: [] + +# The maximum amount of storage a mailbox can use in kilobytes. Supports b/k/M/G/T/% suffixes +quota: "" + +# The amount a mailbox can go over quota. Works only for accepting messages. Value in %, defaults to 10 +quota_grace: "10" ``` **userdict** diff --git a/defaults/main.yml b/defaults/main.yml index 024a2e613c86ee443415861121992007f0b2a7e6..aa1815706ff0e4218d2b79bdd381079e216b9dfc 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -8,3 +8,5 @@ dovecot: - plain - login user: [] + quota: "" + quota_grace: "10" diff --git a/tasks/main.yml b/tasks/main.yml index 1737ac8a7a061f6440e0ef7578e6447877139064..379903a0ca4e78173dd155dd0759212484638538 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -42,7 +42,9 @@ - { src: "10-mail.conf.j2", dest: "/etc/dovecot/conf.d/10-mail.conf" } - { src: "15-lda.conf.j2", dest: "/etc/dovecot/conf.d/15-lda.conf" } - { src: "15-mailboxes.conf.j2", dest: "/etc/dovecot/conf.d/15-mailboxes.conf" } + - { src: "20-imap.conf.j2", dest: "/etc/dovecot/conf.d/20-imap.conf" } - { src: "20-managesieve.conf.j2", dest: "/etc/dovecot/conf.d/20-managesieve.conf" } + - { src: "90-quota.conf.j2", dest: "/etc/dovecot/conf.d/90-quota.conf" } - { src: "auth-system.conf.j2", dest: "/etc/dovecot/conf.d/auth-system.conf" } - { src: "auth-ldap.conf.j2", dest: "/etc/dovecot/conf.d/auth-ldap.conf" } - { src: "dovecot-ldap.conf.ext.j2", dest: "/etc/dovecot/dovecot-ldap.conf.ext" } diff --git a/templates/10-mail.conf.j2 b/templates/10-mail.conf.j2 index e991cc85c637ad57b7bc47245b430e2f8a54c963..5b424ca00b1b456dad900f189d450a5dfd2a1697 100644 --- a/templates/10-mail.conf.j2 +++ b/templates/10-mail.conf.j2 @@ -212,7 +212,11 @@ last_valid_gid = {{ vmail_group.gid }} # 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. +{% if dovecot.quota %} +mail_plugins = quota +{% else %} #mail_plugins = +{% endif %} ## ## Mailbox handling optimizations diff --git a/templates/15-lda.conf.j2 b/templates/15-lda.conf.j2 index 81d36755b2ce7bbbcee68f60a85cc29de313e700..fa5f498b8d396271dff44e8bb19e7b9f7440d287 100644 --- a/templates/15-lda.conf.j2 +++ b/templates/15-lda.conf.j2 @@ -4,15 +4,19 @@ # Address to use when sending rejection mails. # Default is postmaster@<your domain>. %d expands to recipient domain. -#postmaster_address = +#postmaster_address = # Hostname to use in various parts of sent mails (e.g. in Message-Id) and # in LMTP replies. Default is the system's real hostname@domain. -#hostname = +#hostname = # If user is over quota, return with temporary failure instead of # bouncing the mail. +{% if dovecot.quota %} +quota_full_tempfail = yes +{% else %} #quota_full_tempfail = no +{% endif %} # Binary to use for sending mails. #sendmail_path = /usr/sbin/sendmail @@ -32,7 +36,7 @@ #recipient_delimiter = + # Header where the original recipient address (SMTP's RCPT TO: address) is taken -# from if not available elsewhere. With dovecot-lda -a parameter overrides this. +# from if not available elsewhere. With dovecot-lda -a parameter overrides this. # A commonly used header for this is X-Original-To. #lda_original_recipient_header = diff --git a/templates/20-imap.conf.j2 b/templates/20-imap.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..9929812f9dd78f3db7e64d5513d134b4bd98fad0 --- /dev/null +++ b/templates/20-imap.conf.j2 @@ -0,0 +1,102 @@ +## +## IMAP specific settings +## + +# If nothing happens for this long while client is IDLEing, move the connection +# to imap-hibernate process and close the old imap process. This saves memory, +# because connections use very little memory in imap-hibernate process. The +# downside is that recreating the imap process back uses some resources. +#imap_hibernate_timeout = 0 + +# Maximum IMAP command line length. Some clients generate very long command +# lines with huge mailboxes, so you may need to raise this if you get +# "Too long argument" or "IMAP command line too large" errors often. +#imap_max_line_length = 64k + +# IMAP logout format string: +# %i - total number of bytes read from client +# %o - total number of bytes sent to client +# %{fetch_hdr_count} - Number of mails with mail header data sent to client +# %{fetch_hdr_bytes} - Number of bytes with mail header data sent to client +# %{fetch_body_count} - Number of mails with mail body data sent to client +# %{fetch_body_bytes} - Number of bytes with mail body data sent to client +# %{deleted} - Number of mails where client added \Deleted flag +# %{expunged} - Number of mails that client expunged, which does not +# include automatically expunged mails +# %{autoexpunged} - Number of mails that were automatically expunged after +# client disconnected +# %{trashed} - Number of mails that client copied/moved to the +# special_use=\Trash mailbox. +# %{appended} - Number of mails saved during the session +#imap_logout_format = in=%i out=%o deleted=%{deleted} expunged=%{expunged} \ +# trashed=%{trashed} hdr_count=%{fetch_hdr_count} \ +# hdr_bytes=%{fetch_hdr_bytes} body_count=%{fetch_body_count} \ +# body_bytes=%{fetch_body_bytes} + +# Override the IMAP CAPABILITY response. If the value begins with '+', +# add the given capabilities on top of the defaults (e.g. +XFOO XBAR). +#imap_capability = + +# How long to wait between "OK Still here" notifications when client is +# IDLEing. +#imap_idle_notify_interval = 2 mins + +# ID field names and values to send to clients. Using * as the value makes +# Dovecot use the default value. The following fields have default values +# currently: name, version, os, os-version, support-url, support-email. +#imap_id_send = + +# ID fields sent by client to log. * means everything. +#imap_id_log = + +# Workarounds for various client bugs: +# delay-newmail: +# Send EXISTS/RECENT new mail notifications only when replying to NOOP +# and CHECK commands. Some clients ignore them otherwise, for example OSX +# Mail (<v2.1). Outlook Express breaks more badly though, without this it +# may show user "Message no longer in server" errors. Note that OE6 still +# breaks even with this workaround if synchronization is set to +# "Headers Only". +# tb-extra-mailbox-sep: +# Thunderbird gets somehow confused with LAYOUT=fs (mbox and dbox) and +# adds extra '/' suffixes to mailbox names. This option causes Dovecot to +# ignore the extra '/' instead of treating it as invalid mailbox name. +# tb-lsub-flags: +# Show \Noselect flags for LSUB replies with LAYOUT=fs (e.g. mbox). +# This makes Thunderbird realize they aren't selectable and show them +# greyed out, instead of only later giving "not selectable" popup error. +# +# The list is space-separated. +#imap_client_workarounds = + +# Host allowed in URLAUTH URLs sent by client. "*" allows all. +#imap_urlauth_host = + +# Enable IMAP LITERAL- extension (replaces LITERAL+) +#imap_literal_minus = no + +# What happens when FETCH fails due to some internal error: +# disconnect-immediately: +# The FETCH is aborted immediately and the IMAP client is disconnected. +# disconnect-after: +# The FETCH runs for all the requested mails returning as much data as +# possible. The client is finally disconnected without a tagged reply. +# no-after: +# Same as disconnect-after, but tagged NO reply is sent instead of +# disconnecting the client. If the client attempts to FETCH the same failed +# mail more than once, the client is disconnected. This is to avoid clients +# from going into infinite loops trying to FETCH a broken mail. +#imap_fetch_failure = disconnect-immediately + +protocol imap { + # Space separated list of plugins to load (default is global mail_plugins). + {% if dovecot.quota -%} + mail_plugins = $mail_plugins imap_quota + {% else -%} + #mail_plugins = $mail_plugins + {% endif -%} + + # Maximum number of IMAP connections allowed for a user from each IP address. + # NOTE: The username is compared case-sensitively. + #mail_max_userip_connections = 10 +} diff --git a/templates/90-quota.conf.j2 b/templates/90-quota.conf.j2 new file mode 100644 index 0000000000000000000000000000000000000000..d0751725001a0cc7715611071c7e6b3c2966efae --- /dev/null +++ b/templates/90-quota.conf.j2 @@ -0,0 +1,112 @@ +## +## Quota configuration. +## + +# Note that you also have to enable quota plugin in mail_plugins setting. +# <doc/wiki/Quota.txt> + +## +## Quota limits +## + +# Quota limits are set using "quota_rule" parameters. To get per-user quota +# limits, you can set/override them by returning "quota_rule" extra field +# from userdb. It's also possible to give mailbox-specific limits, for example +# to give additional 100 MB when saving to Trash: + +plugin { + {% if dovecot.quota -%} + quota_rule = *:storage={{ dovecot.quota }} + + # What to give back to postfix when checking quotas + quota_status_success = DUNNO + quota_status_nouser = DUNNO + quota_status_overquota = "552 5.2.2 Mailbox is full" + {% else %} + #quota_rule = *:storage=1G + #quota_rule2 = Trash:storage=+100M + {% endif -%} + + # LDA/LMTP allows saving the last mail to bring user from under quota to + # over quota, if the quota doesn't grow too high. Default is to allow as + # long as quota will stay under 10% above the limit. Also allowed e.g. 10M. + {% if dovecot.quota_grace -%} + quota_grace = {{ dovecot.quota_grace }}%% + {% else -%} + #quota_grace = 10%% + {% endif %} + + # Quota plugin can also limit the maximum accepted mail size. + #quota_max_mail_size = 100M +} + +## +## Quota warnings +## + +# You can execute a given command when user exceeds a specified quota limit. +# Each quota root has separate limits. Only the command for the first +# exceeded limit is executed, so put the highest limit first. +# The commands are executed via script service by connecting to the named +# UNIX socket (quota-warning below). +# Note that % needs to be escaped as %%, otherwise "% " expands to empty. + +plugin { + #quota_warning = storage=95%% quota-warning 95 %u + #quota_warning2 = storage=80%% quota-warning 80 %u +} + +# Example quota-warning service. The unix listener's permissions should be +# set in a way that mail processes can connect to it. Below example assumes +# that mail processes run as vmail user. If you use mode=0666, all system users +# can generate quota warnings to anyone. +#service quota-warning { +# executable = script /usr/local/bin/quota-warning.sh +# user = dovecot +# unix_listener quota-warning { +# user = vmail +# } +#} + +## +## Quota backends +## + +# Multiple backends are supported: +# dirsize: Find and sum all the files found from mail directory. +# Extremely SLOW with Maildir. It'll eat your CPU and disk I/O. +# dict: Keep quota stored in dictionary (eg. SQL) +# maildir: Maildir++ quota +# fs: Read-only support for filesystem quota + +plugin { + #quota = dirsize:User quota + {% if dovecot.quota -%} + quota = maildir:User quota + {% else -%} + #quota = maildir:User quota + {% endif -%} + #quota = dict:User quota::proxy::quota + #quota = fs:User quota +} + +# Multiple quota roots are also possible, for example this gives each user +# their own 100MB quota and one shared 1GB quota within the domain: +plugin { + #quota = dict:user::proxy::quota + #quota2 = dict:domain:%d:proxy::quota_domain + #quota_rule = *:storage=102400 + #quota2_rule = *:storage=1048576 +} + +{% if dovecot.quota %} +# add a service so that postfix can check quota when receiving mail +service quota-status { + executable = quota-status -p postfix + inet_listener { + address = 127.0.0.1 + port = 12340 + } + client_limit = 1 +} +{% endif %}