How to handle external alias with dspam as daemon between postfix and dovecot with virtual domains?

I've got the following situation for incoming mail with Postfix 2.9.6, DSpam 3.10.1 and Dovecot 2.1.7:

Incoming Mail -> SMTP -> LMTP -> DSpam (as daemon) -> LMTP -> Dovecot

I've got virtual domains with virtual mailboxes. Everything works fine so far.

A problem now arises with (virtual?) aliases that point to an external domain. Assume, I have the following virtual domains:

virtualdomain1.com
virtualdomain2.com

which I'm handling mail for. The server itself runs at

mydomain.com

If I add an alias now that points to an external domain, e.g.:

[email protected] -> [email protected]

then (as far as I can follow the log), DSpam checks the mail, passes it over to Dovecot via LMTP and Dovecot rejects the mail as [email protected] is unknown (what of course is true).

So how is the correct setup in order to handle aliases for virtual domains? If possible, I'd also like to check incoming mail for the virtual aliases.

The log of an incoming message to [email protected] is:

postfix/smtpd[23910]: connect from xxx.anyhost.com[1.2.3.4]
postfix/smtpd[23910]: NOQUEUE: filter: RCPT from xxx.anyhost.com[1.2.3.4]: <[email protected]>: Recipient address triggers FILTER lmtp:unix:/dspam/dspam.sock; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<anyhost.com>
postfix/smtpd[23910]: D91D0771AF70: client=xxx.anyhost.com[1.2.3.4]
postfix/cleanup[23917]: D91D0771AF70: message-id=<[email protected]>
postfix/smtpd[23910]: disconnect from xxx.anyhost.com[1.2.3.4]
postfix/qmgr[23278]: D91D0771AF70: from=<[email protected]>, size=1030, nrcpt=1 (queue active)
dovecot: lmtp(23920): Debug: none: root=, index=, control=, inbox=, alt=
dovecot: lmtp(23920): Connect from local
dovecot: lmtp(23920): Debug: Loading modules from directory: /usr/lib/dovecot/modules
dovecot: lmtp(23920): Debug: Module loaded: /usr/lib/dovecot/modules/lib90_sieve_plugin.so
dovecot: auth-worker(23921): mysql(127.0.0.1): Connected to database postfixadmin
dspam[9421]: Got error 550 in response to RCPT TO: 550 5.1.1 <[email protected]> User doesn't exist: [email protected]#015
dovecot: auth-worker(23921): sql([email protected]): unknown user
dovecot: lmtp(23920): Debug: auth input:
dovecot: lmtp(23920): Disconnect from local: Client quit (in RCPT TO)
postfix/lmtp[23918]: D91D0771AF70: to=<[email protected]>, orig_to=<[email protected]>, relay=mail.mydomain.com[/dspam/dspam.sock], delay=0.98, delays=0.47/0.01/0/0.5, dsn=5.3.0, status=bounced (host mail.mydomain.com[/dspam/dspam.sock] said: 530 5.3.0 <[email protected]> Fatal: 550 5.1.1 <[email protected]> User doesn't exist: [email protected] (in reply to end of DATA command))
postfix/cleanup[23917]: 149CB771AF72: message-id=<[email protected]>
postfix/bounce[23923]: D91D0771AF70: sender non-delivery notification: 149CB771AF72
postfix/qmgr[23278]: 149CB771AF72: from=<>, size=3182, nrcpt=1 (queue active)
postfix/qmgr[23278]: D91D0771AF70: removed
postfix/smtp[23925]: 149CB771AF72: to=<[email protected]>, relay=mx.mydomain.com[1.2.3.5]:25, delay=3.9, delays=0.26/0.01/0.09/3.6, dsn=2.0.0, status=sent (250 OK id=1YY9Ne-0007eJ-Hp)
postfix/qmgr[23278]: 149CB771AF72: removed

The postfix main.cf: smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

readme_directory = no

# BECAUSE we use Dovecot for authentication we also use its certificates
smtpd_tls_cert_file=/etc/dovecot/dovecot.pem
smtpd_tls_key_file=/etc/dovecot/private/dovecot.pem
smtpd_use_tls=yes
smtpd_tls_auth_only = yes

#Handing off local delivery to Dovecot's LMTP, and telling it where to store mail
virtual_transport = lmtp:unix:private/dovecot-lmtp

#Virtual domains, users, and aliases
virtual_mailbox_domains = proxy:mysql:$config_directory/mysql_virtual_domains_maps.cf
virtual_mailbox_maps =
    proxy:mysql:$config_directory/mysql_virtual_mailbox_maps.cf,
    proxy:mysql:$config_directory/mysql_virtual_alias_domain_mailbox_maps.cf,
    proxy:mysql:$config_directory/mysql_virtual_alias_domain_catchall_maps.cf
virtual_alias_maps =
    proxy:mysql:$config_directory/mysql_virtual_alias_maps.cf,
    proxy:mysql:$config_directory/mysql_virtual_alias_domain_maps.cf
virtual_mailbox_limit = proxy:mysql:$config_directory/mysql_virtual_mailbox_limit_maps.cf

myhostname = mail.me.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = localhost, $myhostname
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 1000000000
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

#Enabling SMTP for authenticated users, and handing off authentication to Dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

smtpd_recipient_restrictions =
        permit_sasl_authenticated,
        permit_mynetworks,
        reject_unauth_destination,
        check_recipient_access pcre:/etc/postfix/dspam_filter_access,
        permit

The dspam_filter_access file:

/./  FILTER lmtp:unix:/dspam/dspam.sock

One last note: If I comment this line

#check_recipient_access pcre:/etc/postfix/dspam_filter_access,

everything works fine, but of course without spam checking.


Solution 1:

In your current setup above, both dovecot and dspam can't reroute your email to proper destination. Especially for dovecot, it only can accept the email based on domain configuration.

The solution is shange your dspam setup deliver email back to postfix after scanning it instead sending it to dovecot. With this setup, after scanning postfix routing engine will reroute your email

  • to outside mail server, if the recipient address points to external domain
  • to dovecot, if the recipient address match your virtual domain

In other words

[ Outside ] --smtp--> [ Postfix ] --lmtp--> [ dspam ] --smtp--> [ postfix ] --> dovecot (if localdomain) or another mail server (if external domain)

You can configure it like dspam setup in this tutorial. Summary of steps

  1. Add second postfix smtpd listener in master.cf, for example localhost:10026
  2. Instead using dspam_filter_access to deliver email to dspam, you can use content_filter parameter
  3. Change the configuration of Delivery{Host, Port, Proto} in DSPAM to postfix second smtpd
  4. Disable address mappings (no_address_mappings) content_filter and another restriction in second smtpd