Skip to main content
Version: 1.2

Zimbra configuration

Zimbra runs its own Postfix as the zimbra user and regenerates main.cf from its configuration on every zmmtactl restart or zmmtactl reload.

warning

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.

info

Start the milter service first (see Single server, or MTA servers in a multi-server installation) before wiring Zimbra to it. This way mail flows through the milter as soon as the MTA reloads.

One MTA at a time​

Every MTA server sends mail to the milter on its own host (localhost:7080), so the settings are made per server with zmprov ms and the commands below are run on each MTA host, after the milter on that host is running. $(zmhostname) resolves to the host you run them on.

In a multi-server installation, do not set the same attributes globally with zmprov mcf: an MTA whose milter is not installed yet would then hand mail to a milter that is not there.

Commands​

Run the following as the zimbra user on the Zimbra MTA host:

sudo su - zimbra
zmprov ms $(zmhostname) zimbraMilterServerEnabled TRUE
zmmilterctl start
zmprov ms $(zmhostname) zimbraMtaSmtpdMilters "inet:localhost:7080"
zmprov ms $(zmhostname) zimbraMtaNonSmtpdMilters "inet:localhost:7080"
zmprov ms $(zmhostname) zimbraMtaMilterDefaultAction accept
zmmtactl reload

Description​

Switch to the zimbra user. All zmprov and zmmtactl commands must run as this user.

sudo su - zimbra
warning

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.

zmprov ms $(zmhostname) zimbraMilterServerEnabled TRUE
zmmilterctl start

Register the milter for mail arriving over SMTP (from external clients and other mail servers).

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.

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.

zmprov ms $(zmhostname) zimbraMtaMilterDefaultAction accept

Reload the Zimbra MTA so Postfix regenerates its configuration with the milter settings.

zmmtactl reload

Verify​

Confirm Postfix picked up the milter after the reload (still as the zimbra user):

postconf smtpd_milters non_smtpd_milters milter_default_action

Expected output:

smtpd_milters = inet:localhost:7080
non_smtpd_milters = inet:localhost:7080
milter_default_action = accept

In a multi-server installation, list the MTA servers and check that each of them has the milter set:

zmprov gas mta
zmprov gs <mta-host> zimbraMtaSmtpdMilters zimbraMtaNonSmtpdMilters zimbraMtaMilterDefaultAction

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:

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, on each MTA host:

zmlocalconfig -e postfix_smtpd_milters=inet:localhost:7080
zmlocalconfig -e postfix_non_smtpd_milters=inet:localhost:7080
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​