Serving Dovecot mailbox quota status to Postfix

Dovecot 2.2 introduces a policy-Service built especially for Postfix. By querying this Dovecot-policy-Service, Postfix can now check a user's mailbox quota before actually delivering a mail to Dovecot. It doesn't have to accept the message only to find out a little later Dovecot will not accept it.

This saves ressources, avoids unnecessary backscatter and - probably more harmful - to have the mail system blacklisted for backscattering.

Status Quo

/media/uploads/noquota.svg

Mail systems split into front- and backend components - boundary filter and mailstore - are problematic when it comes to handling quota properly: Without real knowledge about a mailbox's quota status the frontend server accepts the message and transports it towards the backend system -- only to find out the backend system will not accept it, because the mailbox turns out to be 'over quota'.

The server needs to generate a bounce message to tell the sender the message could not be delivered. The mail system became a backscatter source.

The Improvement

/media/uploads/quota-status.svg

Dovecot's new quota-status-service helps to avoid this dilemma. It provides quota status information to Postfix. This way Postfix can tell (while the client is still in the SMTP session) if the recipients mailbox is over quota - or not. Implemented as a policy service the information is available over network. This makes it so useful in mail systems whose components are distributed among servers.

How it works

First of all you need to activate and configure the quota-status-service in Dovecots dovecot.conf:

plugin {
    ...
    quota_grace = 10%%
    # 10% is the default
    quota_status_success = DUNNO
    quota_status_nouser = DUNNO
    quota_status_overquota = "552 5.2.2 Mailbox is full"
    ...
}

service quota-status {
    executable = quota-status -p postfix
    inet_listener {
        port = 12340
        # You can choose any port you want
    }
    client_limit = 1
}
quota_grace
quota_grace configures how much a mailbox may go over quota: If a mailbox is almost over quota, but not yet completely, quota_grace would allow Dovecot to accept messages as long as the resulting mailbox size would not exceed the 10% grace limit.

Note

quota_grace is a global parameter. It applies to all subsystems of the Dovecot mail server (LDA, LMTP, IMAP).

quota_status_*
quota_status_* settings modify how the server responds. Setting quota_status_success to DUNNO would allow (Postfix) to evaluate restrictions that follow the check_policy_service test noted below.
quota_status_nouser
Setting quota_status_nouser to DUNNO is great if your boundary filter sends messages to two, different mailstores. If the other system is not a Dovecot server and if the mailbox in question is not on the Dovecot server, Dovecot will simply skip the question - instead of telling Postfix to reject the message.

In order to use your newly configured Dovecot policy-service, you need to tell Postfix to communicate with the service in main.cf:

smtpd_recipient_restrictions =
    ...
    check_policy_service inet:mailstore.example.com:12340

In this example the frontend server's very last test in smtpd_recipient_restrictions instructs Postfix to contact the Dovecot policy-server at mailstore.example.com on port 12340.

Tip

Add warn_if_reject in the same line before check_policy_service while you test. Postfix will not reject messages if the mailbox is over quota; it will only issue a warning in the log file.

A reject due to over quota looks about like this in the log:

Apr  5 15:03:00 mail2 postfix/smtpd[24261]: NOQUEUE: reject: RCPT from \
inbound.example.com[192.0.2.1]: 552 5.2.2 <firstname.lastname@example.invalid>: \
Recipient address rejected: Quota exceeded (mailbox for user is full); \
from=<r@sys4.de> to=<firstname.lastname@example.invalid> proto=ESMTP \
helo=<sending.domain.invalid>

Comments

  1. Alex

    Alex (1 year, 8 months) # Reply

    Cool stuff! thanks for sharing.

  2. D-Alan

    D-Alan (1 year, 2 months) # Reply

    Hi, Great. How to limit the sending mail size by this function?

  3. eyes

    eyes (2 months, 1 week) # Reply

    Please tell me about main.cf.

    I wrote,
    smtpd_recipient_restrictions =
    check_policy_service inet:mailstore.example.com:12340

    But mail.log said,
    Oct 6 21:44:40 mail1 postfix/smtpd[23158]: fatal: parameter "smtpd_recipient_restrictions": specify at least one working instance of: check_relay_domains, reject_unauth_destination, reject, defer or defer_if_permit

    please tell me about smtpd_recipient_restrictions.

Leave a comment.
Your Comment

×