Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Split mail delivery

Split mail delivery

####################################################################
## THIS IS A DRAFT DOCUMENT.                                      ##
## DO NOT APPLY IT ON PRODUCTION SERVER WITHOUT TESTING.          ##
####################################################################

Summary

If you're hosting same mail domain on 2 servers, e.g. Google G-suite and iRedMail server, you can follow this tutorial to update iRedMail server settings to relay non-existing addresses (under the hosted mail domain) to G-suite. For example, mailbox xyz@domain.com exists on Gsuite but NOT on iRedMail, with this turotial, you're able to relay email sent to xyz@ to Gsuite.

WARNING

  • Although it's been tested locally and working, but it's not yet tested in production, so it may have some issue that i'm not aware yet. Please try it with a testing machine first, and report any issue you found in iRedMail forum: https://forum.iredmail.org/
  • If we implement this feature in iRedMail someday, the new SQL column mentioned in the document (domain.split_transport) MAY be different. You need to track the change by check the detailed release notes.

Add required new SQL column domain.split_transport

USE vmail;
ALTER TABLE domain ADD COLUMN split_transport VARCHAR(255) NOT NULL DEFAULT '';

Update Postfix configuration

  • With updated transport_maps, Postfix will query transport in order:
    • per-user transport
    • per-mailing-list transport
    • if no per-user or per-mailing-list transport, query transport for split deliver if the domain is configured to relay email which is sent to local domain but the recipient address doesn't exist locally.
    • if none of above 3 matches, query per-domain transport
  • With updated virtual_mailbox_maps, if split delivery is enabled, return a value so that Postfix considers the address exists locally.

Update Postfix main.cf

Update file /etc/postfix/main.cf, add 2 lines:

transport_maps =
    proxy:mysql:/etc/postfix/mysql/transport_maps_user.cf
    proxy:mysql:/etc/postfix/mysql/transport_maps_maillist.cf
    proxy:mysql:/etc/postfix/mysql/transport_maps_split.cf      # <- Add this line
    proxy:mysql:/etc/postfix/mysql/transport_maps_domain.cf

virtual_mailbox_maps =
    proxy:mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf
    proxy:mysql:/etc/postfix/mysql/virtual_mailbox_split.cf     # <- Add this line

Create required files

###########################################
# WARNING
#
# Please replace the sample password by the real one which is used
# in other files under `/etc/postfix/mysql/*.cf`.
###########################################
  • /etc/postfix/mysql/transport_maps_split.cf
hosts       = 127.0.0.1:3306
user        = vmail
password    = 030b94feae9eab379a0a3c2cecd9775b
dbname      = vmail
query       = SELECT split_transport FROM domain WHERE domain='%d' AND backupmx=0 AND split_transport<>'' AND active=1
  • /etc/postfix/mysql/virtual_mailbox_split.cf
hosts       = 127.0.0.1:3306
user        = vmail
password    = 030b94feae9eab379a0a3c2cecd9775b
dbname      = vmail
query       = SELECT split_transport FROM domain WHERE NOT EXISTS (SELECT address FROM forwardings WHERE address='%s' AND active=1 LIMIT 1) AND domain='%d' AND backupmx=0 AND split_transport<>'' AND active=1

Make sure these 2 new files are owned by root:postfix with permission 0640, and restart Postfix service:

cd /etc/postfix/mysql/
chown root:postfix *split*.cf
chmod 0640 *split*.cf
service postfix restart

Update iRedAPD config file

iRedAPD plugin reject_sender_login_mismatch will reject emails relayed from another server if the sender domain is hosted on iRedMail, so you need to either disable this plugin, or tell iRedAPD to accept the "forged" emails by adding this setting in /opt/iredapd/settings.py:

ALLOWED_FORGED_SENDERS = ['domain.com']

Restarting iredapd service is required after the change.

Sample usage

Mailbox xyz@domain.com exists on Gsuite but NOT on iRedMail, to relay email sent to xyz@ to Gsuite, please set the relay address with SQL command like below:

USE vmail;
UPDATE domain SET split_transport='smtp:ASPMX.L.GOOGLE.COM:25' WHERE domain='domain.com';

Value of split_transport must be a valid Postfix transport. FYI: http://www.postfix.org/transport.5.html

Known issues

  • If either server receives a message sent to a non-existing address, the message will be relayed again and again between 2 servers until one of them decides to end the loop. It's safe to ignore because it's expected (address doesn't exist), but yes it's annoying.
@chrisdent

This comment has been minimized.

Copy link

@chrisdent chrisdent commented Dec 18, 2020

When I used your query in this file /etc/postfix/mysql/transport_maps_split.cf the email never arrived in iredadmin.

Changed the query to:

SELECT split_transport FROM domain WHERE domain='%d' AND NOT EXISTS (select username from mailbox where username='%s') AND backupmx=0 AND split_transport<>'' AND active=1

And then the emails arrived as expected.

@ugleiton

This comment has been minimized.

Copy link

@ugleiton ugleiton commented May 31, 2021

When I used your query in this file /etc/postfix/mysql/transport_maps_split.cf the email never arrived in iredadmin.

Changed the query to:

SELECT split_transport FROM domain WHERE domain='%d' AND NOT EXISTS (select username from mailbox where username='%s') AND backupmx=0 AND split_transport<>'' AND active=1

And then the emails arrived as expected.

tive que fazer o mesmo para receber os emails no iredadmin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment