diff --git a/ansible/roles/ispmail-dovecot/files/10-mail.conf b/ansible/roles/ispmail-dovecot/files/10-mail.conf index a660cb9..382ac69 100644 --- a/ansible/roles/ispmail-dovecot/files/10-mail.conf +++ b/ansible/roles/ispmail-dovecot/files/10-mail.conf @@ -216,7 +216,7 @@ mail_privileged_group = mail # 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 ## ## Mailbox handling optimizations diff --git a/ansible/roles/ispmail-dovecot/files/90-quota.conf b/ansible/roles/ispmail-dovecot/files/90-quota.conf new file mode 100644 index 0000000..6604fc8 --- /dev/null +++ b/ansible/roles/ispmail-dovecot/files/90-quota.conf @@ -0,0 +1,101 @@ +## +## Quota configuration. +## + +# Note that you also have to enable quota plugin in mail_plugins setting. +# + +## +## 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 { + #quota_rule = *:storage=1G + #quota_rule2 = Trash:storage=+100M + + # 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. + #quota_grace = 10%% + + # 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-status { + executable = /usr/lib/dovecot/quota-status -p postfix + unix_listener /var/spool/postfix/private/quota-status { + user = postfix + } +} + +plugin { + quota_status_success = DUNNO + quota_status_nouser = DUNNO + quota_status_overquota = "552 5.2.2 Mailbox is over quota / Mailbox ist voll" +} + +## +## 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 + quota = maildir:User quota + #quota_rule = *:bytes=1000 + #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 +} + +plugin { + quota_warning = storage=95%% quota-warning 95 %u + quota_warning2 = storage=80%% quota-warning 80 %u +} +service quota-warning { + executable = script /usr/local/bin/quota-warning.sh + unix_listener quota-warning { + group = dovecot + mode = 0660 + } +} diff --git a/ansible/roles/ispmail-dovecot/files/auth-sql.conf.ext b/ansible/roles/ispmail-dovecot/files/auth-sql.conf.ext index 93200fe..ccbea86 100644 --- a/ansible/roles/ispmail-dovecot/files/auth-sql.conf.ext +++ b/ansible/roles/ispmail-dovecot/files/auth-sql.conf.ext @@ -17,15 +17,10 @@ passdb { #} userdb { - driver = static - args = uid=vmail gid=vmail home=/var/vmail/%d/%n + driver = sql + args = /etc/dovecot/dovecot-sql.conf.ext } -#userdb { -# driver = sql -# args = /etc/dovecot/dovecot-sql.conf.ext -#} - # If you don't have any user-specific settings, you can avoid the user_query # by using userdb static instead of userdb sql, for example: # diff --git a/ansible/roles/ispmail-dovecot/tasks/main.yml b/ansible/roles/ispmail-dovecot/tasks/main.yml index ed93b1f..cf5191d 100644 --- a/ansible/roles/ispmail-dovecot/tasks/main.yml +++ b/ansible/roles/ispmail-dovecot/tasks/main.yml @@ -40,3 +40,12 @@ - name: Copying Sieve plugin configuration (90-sieve.conf) copy: src=90-sieve.conf dest=/etc/dovecot/conf.d/90-sieve.conf notify: restart dovecot +- name: Copying Quota plugin configuration (90-quota.conf) + copy: src=90-quota.conf dest=/etc/dovecot/conf.d/90-quota.conf + notify: restart dovecot +- name: Copying quota warning shell script to /usr/local/bin + template: + src: quota-warning.sh.j2 + dest: /usr/local/bin/quota-warning.sh + mode: 0750 + notify: restart dovecot diff --git a/ansible/roles/ispmail-dovecot/templates/dovecot-sql.conf.ext.j2 b/ansible/roles/ispmail-dovecot/templates/dovecot-sql.conf.ext.j2 index 6aec2cc..521607d 100644 --- a/ansible/roles/ispmail-dovecot/templates/dovecot-sql.conf.ext.j2 +++ b/ansible/roles/ispmail-dovecot/templates/dovecot-sql.conf.ext.j2 @@ -145,4 +145,9 @@ driver = mysql connect = host=127.0.0.1 dbname=mailserver user=mailserver password={{ispmail_mysql_mailserver_password}} -password_query = SELECT email as user, password FROM virtual_users WHERE email='%u'; +user_query = SELECT email as user, \ + concat('*:bytes=', quota) AS quota_rule, \ + '/var/vmail/%d/%n' AS home, \ + 5000 AS uid, 5000 AS gid \ + FROM virtual_users WHERE email='%u'; +password_query = SELECT password FROM virtual_users WHERE email='%u'; diff --git a/ansible/roles/ispmail-dovecot/templates/quota-warning.sh.j2 b/ansible/roles/ispmail-dovecot/templates/quota-warning.sh.j2 new file mode 100644 index 0000000..b5290de --- /dev/null +++ b/ansible/roles/ispmail-dovecot/templates/quota-warning.sh.j2 @@ -0,0 +1,11 @@ +#!/bin/sh +PERCENT=$1 +USER=$2 +cat << EOF | /usr/lib/dovecot/dovecot-lda -d $USER -o "plugin/quota=maildir:User quota:noenforcing" +From: postmaster@{{ispmail_fqdn}} +Subject: Quota warning - $PERCENT% reached + +Your mailbox can only store a limited amount of emails. +Currently it is $PERCENT% full. If you reach 100% then +new emails cannot be stored. Thanks for your understanding. +EOF diff --git a/ansible/roles/ispmail-postfix/tasks/main.yml b/ansible/roles/ispmail-postfix/tasks/main.yml index f5a344d..7ccbc89 100644 --- a/ansible/roles/ispmail-postfix/tasks/main.yml +++ b/ansible/roles/ispmail-postfix/tasks/main.yml @@ -78,3 +78,6 @@ - name: Make Postfix listen on all interfaces command: postconf inet_interfaces=all + +- name: Enable user quota checking + command: "postconf 'smtpd_recipient_restrictions = reject_unauth_destination check_policy_service unix:private/quota-status'"