Hi all.
Receiving an email for an alias, I got those errors:
<alias@domain.tld>Recipient address rejected: Unknown user;
I realized this happened when postfix queries dovecot about user quota.
Basically, what happens is that postfix queries dovecot using the virutal alias as name, not the virtual user. And since dovecot doesn't find a user under that name, it returns an error and postfix rejects the mail.
Configuration
I followed the docs at https://doc.dovecot.org/latest/core/plugins/quota.html when setting up the server.
/etc/postfix/main.cf
smtpd_recipient_restrictions =
check_policy_service unix:private/quota-status
/etc/dovecot/conf.d/90-quota.conf
service quota-status {
executable = quota-status -p postfix
unix_listener /var/spool/postfix/private/quota-status {
user = postfix
}
client_limit = 1
}
/etc/dovecot/conf.d/auth-sql.conf.ext
userdb sql {
query = SELECT '/var/mail/vmail/'||maildir AS home, 110 AS uid, 113 AS gid, quota || 'B' AS quota_storage_size FROM mailbox WHERE username = '%{user}'
iterate_query = SELECT username FROM mailbox
}
Solution 1: modify user query
This issue was reported and analyzed here:
https://dovecot.dovecot.narkive.com/FtjhqCuU/postfix-aliases-with-quota-status-service
and there:
https://github.com/docker-mailserver/docker-mailserver/issues/2091
A comment (https://dovecot.dovecot.narkive.com/FtjhqCuU/postfix-aliases-with-quota-stat...) suggests to modify the SQL query to also look for aliases.
I modified my query like so:
query = SELECT '/var/mail/vmail/'||maildir AS home, 110 AS uid, 113 AS gid, quota || 'B' AS quota_storage_size FROM mailbox JOIN alias ON mailbox.username = alias.goto WHERE alias.address = '%{user}';
and it seemed to work.
I mean, I can query user quota with an alias:
doveadm quota get -u alias@domain.tld
but the iterate query ignores aliases so
doveadm quota get -A
only lists users, not aliases (which is what I want) and I can't IMAP login using aliases (which is also what I want) since I didn't modify the password query either.
I find this configuration slightly inconsistent: the user query returns aliases, not the iterate query. Is the user query really meant to return aliases as well?
Also, I realized this query is broken for alias to multiple addresses. I'd get the following error:
Recipient address rejected: Unknown user
Surprisingly, it seems to only affect messages from an external source to an alias pointing to an external mailbox. Messages submitted locally (and perhaps messages sent to an alias to local destinations only, I'm not sure) were not affected.
Solution 2: ignore aliases, it will fail later anyway
On another server, I had this configuration:
/etc/dovecot/conf.d $ vi 90-quota.conf
(Don't put this in plugin on dovecot 2.4+.)
plugin {
quota_status_success = DUNNO
quota_status_nouser = DUNNO
quota_status_overquota = "552 5.2.2 Mailbox is full"
}
The alias is unknown so the check returns DUNNO and postfix lets the message pass (postfix log read "delivered via spamassassin service") but then it fails at sieve stage when writing the message:
sieve: msgid=<xxx>: failed to store into mailbox 'INBOX': Quota exceeded (mailbox for user is full)
The result is what is expected: the message is rejected due to mailbox full. But I don't think it was intended to work this way. And since the message is quota-rejected at sieve stage, I could remove the check_policy_service line since it will be rejected for a virtual user (not alias) as well anyway. Right?
Question
What is the recommended configuration to let postfix use dovecot to check quotas for virtual aliases? I couldn't find documentation for this specific use case.
Ideally, postfix would query using the resolved user, not the alias. Can this be achieved?
Should I remove the check and rely on the fact that writing the message fails at a later step anyway?
Thanks.
(Question also posted on ServerFault: https://serverfault.com/questions/1197914/how-to-let-postfix-use-dovecot-to-...)