Milter configuration
This page configures the Zimbra MTA of a single server installation. In a multi-server installation, configure every MTA server as described in Milters configuration.
Zimbra runs its own Postfix as the zimbra user and regenerates main.cf from its configuration on every zmmtactl restart or zmmtactl reload.
Do not edit Zimbra's main.cf directly - the changes will be lost on the next MTA restart. Use zmprov so the milter settings persist.
Start the milter service first (see Installation) before wiring Zimbra to it. This way mail flows through the milter as soon as the MTA reloads.
Commands
The Zimbra MTA sends mail to the milter on the same server (localhost:7080). The settings are made for this server with zmprov ms; $(zmhostname) resolves to its host name.
Run the following on the Zimbra server:
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMilterServerEnabled TRUE'
sudo su - zimbra -c 'zmmilterctl start'
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMtaSmtpdMilters "inet:localhost:7080"'
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMtaNonSmtpdMilters "inet:localhost:7080"'
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMtaMilterDefaultAction accept'
sudo su - zimbra -c 'zmmtactl reload'
Description
All zmprov and zmmtactl commands must run as the zimbra user, so each command switches to it with sudo su - zimbra -c.
Zimbra 8.6 and later have a bug that can overwrite Postfix's smtpd_milters parameter with an empty value, so the milter silently stops receiving mail (Bug 97706). Work around it by enabling Zimbra's own milter server (zimbraMilterServerEnabled) and starting it with zmmilterctl start before configuring the MSH Zimbra Rules milter below, even if you do not otherwise use Zimbra's built-in milter - see the FAQ for what that built-in milter actually does.
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMilterServerEnabled TRUE'
sudo su - zimbra -c 'zmmilterctl start'
Register the milter for mail arriving over SMTP (from external clients and other mail servers).
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMtaSmtpdMilters "inet:localhost:7080"'
Register the milter for locally injected mail (sendmail, cron jobs, local applications). Set it only if you also want internally generated mail filtered.
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMtaNonSmtpdMilters "inet:localhost:7080"'
Set the default action Postfix takes when the milter is unavailable. With accept, mail still flows if the milter is down instead of being deferred. Use tempfail instead if you would rather hold mail when the milter is unavailable.
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMtaMilterDefaultAction accept'
Reload the Zimbra MTA so Postfix regenerates its configuration with the milter settings.
sudo su - zimbra -c 'zmmtactl reload'
Verify
Confirm Postfix picked up the milter after the reload:
sudo su - zimbra -c 'postconf smtpd_milters non_smtpd_milters milter_default_action'
Expected output:
smtpd_milters = inet:localhost:7080, inet:127.0.0.1:7026
non_smtpd_milters = inet:localhost:7080
milter_default_action = accept
Caveats
Zimbra's own milter is also used for distribution-list access control
zimbraMilterServerEnabled is enabled above purely as the Bug 97706 workaround (see the FAQ for what it actually does). If you also actually use Zimbra's built-in milter for distribution-list access control, it populates smtpd_milters with its own socket too. In that case set zimbraMtaSmtpdMilters to a value that includes both sockets, so you do not drop Zimbra's milter:
sudo su - zimbra -c 'zmprov ms $(zmhostname) zimbraMtaSmtpdMilters "inet:localhost:7026 inet:localhost:7080"'
Check the current value with zmprov gs $(zmhostname) zimbraMtaSmtpdMilters before overwriting it.
Older Zimbra versions
Older Zimbra versions may not expose the zimbraMtaSmtpdMilters / zimbraMtaNonSmtpdMilters / zimbraMtaMilterDefaultAction server attributes. Use zmlocalconfig instead:
sudo su - zimbra -c 'zmlocalconfig -e postfix_smtpd_milters=inet:localhost:7080'
sudo su - zimbra -c 'zmlocalconfig -e postfix_non_smtpd_milters=inet:localhost:7080'
sudo su - zimbra -c 'zmlocalconfig -e postfix_milter_default_action=accept'
Either mechanism works; verify what your version uses and avoid configuring the same milter twice.
What's next
- Connect to the web admin UI - log in and create your first rules
- Zimlet configuration - let users change their own attributes used in signatures
- Troubleshooting Zimbra configuration - verify the milter is applied and test the mail flow