Deployment Scenario A: User Migration to Zimbra
We are often asked how to configure the Zimbra Collaboration Suite so that some accounts are moved/migrated to Zimbra but other accounts continue to live on the existing mail system, in what would be a Split domain. This is possible if your mail system offers some of the mail routing features that Zimbra offers.
Deployment Scenario B: Zimbra as a Smart Host or Backup Email Server
Users familiar with configuring Postfix may know this Split Domain concept as Postfix Relay Domains (see for example Chapter 13 of The Book of Postfix by Hildebrandt and Koetter). While this article deals primarily with splitting user accounts on the same domain between a Zimbra and a second mail server, there can be benefits to having Zimbra perform as a Primary system in a Split Domain configuration where users never log in to the Zimbra system.
Since Zimbra can perform inbound email prescreening and also function as an outbound smart host for the secondary mail server, the secondary mail server (say, a Microsoft Exchange server) need not have an MX record in public DNS, saving that secondary mail server from being targetted by spammers directly. This configuration allows Zimbra to serve also as a backup mail server when the secondary server is down (yes, that sounds backwards...)
When the secondary mail server is down, mail destined for that secondary (e.g. Exchange) server will not be bounced back to the original sender immediately and will remain on the Zimbra server until either the secondary server comes back online or Zimbra's attempted mail delivery timeout is reached-whichever comes first. (Note that security for the secondary mail server may be further enhanced under this deployment scenario by setting the firewall protecting the secondary server to block all inbound and outbound port 25 traffic everywhere except to/from the IP of the Zimbra host.)
For this alternate deployment scenario, just follow the instructions below where Zimbra is the Primary system; see Case 1 of Mail Flow for how mail should flow.
Consider this typical Split Domain example:
- Your domain is example.com.
- Your existing mail infrastructure lives on the host "mail.example.com" (assuming single node install for simplicity, though what we are discussing should also work on multi-node).
- Your domain example.com has MX records that point to host "mail.example.com".
- Users "email@example.com" and "firstname.lastname@example.org" exist in the old system.
- You installed Zimbra on the host "zimbra.example.com" and created the domain "example.com" on it also.
- You have migrated the mailbox of user "email@example.com" to the Zimbra system, using one of our migration tools documented elsewhere.
Some issues to consider as a result of such splitting your domain
- The end user "firstname.lastname@example.org", who is not being migrated, will be unaware of the change insofar as regular email is concerned. Global address list (GAL) experience should also not change for this user. There may be some issues around group calendaring between the two systems (assuming your existing infrastructure supports group calendaring); we are working on these issues.
- The end user "email@example.com" will need to be educated and the user's desktop software might need some minor configuration changes. Users accessing mail through POP3 or IMAP will need to modify their POP3/IMAP server settings to point to the Zimbra server. Users accessing mail with Outlook will need the ZCS Connector for Outlook installed and configured to access the Zimbra server. Users who will access mail with the Zimbra Web Client will need the hostname (and port number when services run on non-standard ports) of the new Zimbra server.
- If the user "firstname.lastname@example.org" is using a mail client that has outgoing SMTP configured with SMTP AUTH enabled, and SMTP AUTH functionality is required by your network topology or roaming users, then based on where authentication information lives (a decision you will make below), it may be necessary to change the user's outgoing SMTP setting.
- You will have to pick either the Zimbra system or your existing system to be the "authoritative" system for your domain. Let's call the authoritative system the primary system, and the other one the secondary system.
- The primary MTA must
- be aware of, and accept mail for, all accounts on the domain
- reject on RCPT TO: those accounts that do not exist in either system
- forward mail to the secondary MTA for users hosted there.
- The secondary MTA must
- accept mail for any account allegedly on the domain
- forward mail for all accounts on the domain that are not hosted on the secondary system to the primary MTA.
- The primary MTA must
- Note that because of the above primary/secondary mail routing requirement, it will be necessary to perform some type of provisioniong step on both the secondary and the primary for an account that lives on the secondary system.
- For ease of administration you should keep any Global Address List (GAL) on only one of these systems to avoid duplication. However this requires one of these systems to be able to proxy to the other for GAL. Zimbra can use a non-Zimbra external LDAP server for GAL, see the Managing ZCS Configurations chapter, Managing Global Configurations section. (Admin Guide). If this proxy is not possible some other sync method will need to be developed for consistent GAL access across both systems.
- Zimbra can also use an external LDAP server to authenticate users, see the Managing ZCS Configurations chapter, Managing Global Configurations section. (Admin Guide). You may, for example, have a portal or user page backed by LDAP where passwords are stored. Note that by default Zimbra stores user passwords locally in the Zimbra LDAP. If passwords are managed remotely, it is possible the old system can continue to SMTP authenticate users who live on the Zimbra system. If that is the case, then a Zimbra user with SMTP AUTH can continue to use the old system's MTA as their MTA, assuming it is visible on the network.
How to provision and configure Zimbra as either the primary or as a secondary system.
If you decide to use Zimbra as the primary system, then you should also carefully read the section on how to configure Zimbra as the secondary system - this will show you what functionality is required of your existing mail system so it can be the secondary. The same is true vice versa if you are going to use Zimbra as the secondary system.
Configuring Zimbra as the Primary System
1. Create corresponding accounts on the Zimbra system for all the accounts that will live on the secondary system. Note that email@example.com is not migrating, and lives on the secondary.
$ zmprov ca firstname.lastname@example.org <some_random_password>
2. Configure mail routing for this account so email flows to the secondary system for this account:
$ zmprov ma email@example.com zimbraMailTransport smtp:mail.example.com:25
Note that we are not using any catch all (akin to "luser_relay") tricks here. Primary needs to be authoritative, and if it forwards unknown accounts, then we would have a mail loop.
3. Change your MX record so mail from the internet flows into the Zimbra MTA first. (This is the last step! You will bounce mail if you make this change before configuring the entire system and testing that mail flow is working as desired.)
When you are ready to move a user from the old system to the new system just run this command (where zimbra.example.com is the name of your Zimbra server):
$ zmprov ma firstname.lastname@example.org zimbraMailTransport lmtp:zimbra.example.com:7025
ZCS 5.0.x/6.0.x As Primary
If delivering to a single secondary mail system, configure a catchall on the domain to deliver mail to a secondary mail transport if users for the same domain reside on the second system.
- zmpov cd example.com
- zmprov md example.com zimbraMailCatchAllAddress @example.com zimbraMailCatchAllForwardingAddress @example.com zimbraMailTransport smtp:mail.example.com:25
Mail for Zimbra recipients on the primary system to @example.com will be delivered Zimbra mailboxes. Any address that does not exist on the Zimbra system will be routed to the secondary mail transport. This configuration will likely work with 4.5.x, but it has not been tested.
Configuring Zimbra as the Secondary System
1. The secondary system needs to accept mail for accounts that are hosted on the secondary, but must forward all other mail for accounts on this domain to the primary system.
On a zimbra server, you can accomplish this piece of mail routing with these commands:
$ zmprov md example.com zimbraMailCatchAllAddress @example.com $ zmprov md example.com zimbraMailCatchAllForwardingAddress @example.com $ zmprov md example.com zimbraMailTransport smtp:mail.example.com
If smtp:mail.example.com is an Exchange server, and you have a dns alias smtp:mail5.example.com for external (outside) users to send to, be sure to use the local name. If you don't email will route out, then back in through your firewall, thus getting a new IP address. If Exchange is configured to only accept connections from local servers, this will cause it to drop the connection. If Exchange and Zimbra are on the same internal networks, be sure to use their internal names.
The first two commands (in combination) tell the Zimbra postfix to accept all addresses in the @example.com domain as valid addresses.
The third command establishes default mail routing for the domain. Any users that do not exist on the Zimbra system will have their mail routed according to this rule.
2. We also highly recommend that, in a secondary Zimbra system, you turn off DNS lookups and internet wide message routing from the secondary host and route all mail through the primary. (Especially if hiding the secondaries existence for security as discussed above - ie: when not creating MX/SPF records that would help verify your secondary server as legit.) You can accomplish this by:
$ zmprov mcf zimbraMtaRelayHost mail.example.com $ zmprov mcf zimbraMtaDnsLookupsEnabled FALSE
Make sure to configure mail.example.com to
- accept mail relayed by zimbra.example.com.
- forward mail to zimbra.example.com for accounts hosted on zimbra.
3. After completing the above configurations, run these commands:
$ postfix stop $ postfix start
Examples of Mail Flow
- Zimbra is the primary system
- Mail is sent from the internet
- The account lives on the secondary system
:internet -> :zimbra.example.com postfix server -> :account transport says to use smtp:mail.example.com -> :mail.example.com existing infrastructure MTA -> :mail.example.com existing infrastructure mail store
- Zimbra is the secondary system
- Mail is sent from email@example.com (hosted on zimbra) -> firstname.lastname@example.org (hosted on the old system)
- email@example.com is using the Zimbra AJAX client
:foo's web browser -> :zimbra.example.com tomcat server -> :zimbra.example.com postfix server -> :account not local, finds domain transport setting -> :mail.example.com existing infrastructure MTA -> :mail.example.com existing infrastructure mail store
Avoiding Loops in Delivery
Content from talk page, it should be noted these are untested by QA but possible.
As stated above the primary MTA must "be aware of, and accept mail for, all accounts on the domain / reject on RCPT TO: those accounts that do not exist in either system"
Configuring different systems is beyond the scope of this article, so if you've ignored the above advice and implemented a catchall for non-existant on a primary (say exchange) with a secondary (zimbra) you might run into the following problem:
The exchange gets all the email first, all email that exchange didn't have will be catchall sent to the zimbra. Then zimbra will accept all emails local to it and if catch all is enabled, all non-local-to-exchange and non-local-to-zimbra will be forward again back to the exchange, creating a loop. (In this situation were assuming you'd rather not provision all users on zimbra and set zimbraMailTransport on each account.
So what is needed is to filter invalid emails, but as we have the catchall, we can't use the smtpd_reject_unlisted_recipients, as the catchall is included in there.
Solution for dual catchall situation:
cp /opt/zimbra/conf/postfix_recipient_restrictions.cf /opt/zimbra/conf/postfix_recipient_restrictions.cf.in
In /opt/zimbra/conf/postfix_recipient_restrictions.cf remove the permit and add the check_recipient_access ldap:/opt/zimbra/conf/ldap-emails.cf reject.
Changed file looks like this:
# cat /opt/zimbra/conf/postfix_recipient_restrictions.cf reject_non_fqdn_recipient permit_sasl_authenticated permit_mynetworks reject_unauth_destination reject_unlisted_recipient %%contains VAR:zimbraMtaRestriction reject_invalid_hostname%% %%contains VAR:zimbraMtaRestriction reject_non_fqdn_hostname%% %%contains VAR:zimbraMtaRestriction reject_non_fqdn_sender%% %%contains VAR:zimbraMtaRestriction reject_unknown_client%% %%contains VAR:zimbraMtaRestriction reject_unknown_hostname%% %%contains VAR:zimbraMtaRestriction reject_unknown_sender_domain%% %%explode reject_rbl_client VAR:zimbraMtaRestrictionRBLs%% %%contains VAR:zimbraMtaRestriction check_policy_service unix:private/policy%% check_recipient_access ldap:/opt/zimbra/conf/ldap-emails.cf reject
This checks if the email is valid and accepts the email... else, reject all junk
For the /opt/zimbra/conf/ldap-emails.cf just copy the /opt/zimbra/conf/ldap-vam.cf (virtual alias maps) and removed the catchall entry and add the result_filter = OK. (May be missing the local alias maps, but at least in our case, its unused.)
Original /opt/zimbra/conf/ldap-vam.cf (leave untouched):
server_host = ldap://zimbra.domain:389 server_port = 389 search_base = query_filter = (&(|(zimbraMailDeliveryAddress=%s)(zimbraMailAlias=%s)(zimbraMailCatchAllAddress=%s))(zimbraMailStatus=enabled)) result_attribute = zimbraMailDeliveryAddress,zimbraMailForwardingAddress,zimbraPrefMailForwardingAddress,zimbraMailCatchAllForwardingAddress version = 3 start_tls = yes tls_ca_cert_dir = /opt/zimbra/conf/ca bind = yes bind_dn = uid=zmpostfix,cn=appaccts,cn=zimbra bind_pw = LDAP_PASSWORD timeout = 30
Final /opt/zimbra/conf/ldap-emails.cf (new file):
server_host = ldap://zimbra.domain:389 server_port = 389 search_base = query_filter = (&(|(zimbraMailDeliveryAddress=%s)(zimbraMailAlias=%s)(zimbraMailCatchAllAddress=%s))(zimbraMailStatus=enabled)) result_attribute = zimbraMailDeliveryAddress,zimbraMailForwardingAddress,zimbraPrefMailForwardingAddress result_filter = OK version = 3 start_tls = yes tls_ca_cert_dir = /opt/zimbra/conf/ca bind = yes bind_dn = uid=zmpostfix,cn=appaccts,cn=zimbra bind_pw = LDAP_PASSWORD timeout = 30
This will return OK for each valid email.
Users sending emails via the zimbra webmail will be delivered, because they are in the mynetworks (as localhost), users sending the email remotely via smtp still get delivery, because they will be SASL authenticated to relay via mynetworks.
zimbraMtaMyNetworks must be correct (localhost, local zimbra ip and any special IP that really needs to relay without authentication). If correct, postfix will accept only the local emails and still relay when it needs.