Skip to main content
Version: 1.2

Update

An update replaces the code (jars, launchers, lib/defaults.cf, service units) and keeps everything host-local. Everything host-local lives in /opt/msh-zr/etc/, so the update unpacks the new package with etc/ excluded.

File in etc/On which host (on a single server, all of them)Holds
config.cfEvery hostYour configuration overrides
msh-zr-web.dbWeb admin serverServers, users of the web admin, directory service settings
msh-zr-master.dbWeb admin serverRules, templates and all other settings, the source the servers get their copy from
msh-zr-node.dbEvery MTA serverThe node's copy of the rules and settings, read by the milter
msh-zr-milter.dbEvery MTA serverMessage history and message counts
node.token, node.p12, node.p12.passwordEvery MTA serverThe node's access token and HTTPS certificate
license.id, license.keyEvery hostThe license, sent to the servers by the web admin
keystore.p12Web admin serverThe web admin's HTTPS certificate, if you enabled HTTPS

The scripts/ directory is kept as well: the update replaces only the shipped samples accept.sh, reject.sh and README.txt. Stored attachments in var/attachments/ are kept.

warning

Keep the files in etc/, in particular node.token and node.p12 on the MTA servers. If they are lost, the node creates a new token and certificate, and the web admin no longer accepts the server until you remove it and add it again on the Servers page.

Update order​

Update the MTA servers first and the web admin last, so the web admin never sends rules and settings to a server that is older than itself.

  • Single server: update the one host, all three services at once.
  • Multiple servers: update every MTA server (node and milter), one at a time. Then update the web admin server.

While a server is older than the web admin, the Servers page shows it as Version mismatch. It keeps filtering mail with the rules and settings it received before, and gets the current ones as soon as it is updated.

Back up first​

Copy the etc/ directory of each host before you update it, for example:

sudo cp -a /opt/msh-zr/etc /opt/msh-zr/etc.backup-$(date +%F)

On the web admin server, also export a backup on the Backup & Restore page.

Commands​

Single server (web admin, node and milter)​

sudo systemctl stop msh-zr-web.service msh-zr-node.service msh-zr-milter.service
sudo tar zxvf msh-zr-<VERSION>.tgz -C /opt --exclude='msh-zr/etc/*'
sudo sh /opt/msh-zr/lib/fixperms.sh
sudo systemctl daemon-reload
sudo systemctl start msh-zr-node.service msh-zr-milter.service msh-zr-web.service

MTA server (node and milter)​

sudo systemctl stop msh-zr-node.service msh-zr-milter.service
sudo tar zxvf msh-zr-<VERSION>.tgz -C /opt --exclude='msh-zr/etc/*'
sudo sh /opt/msh-zr/lib/fixperms.sh
sudo systemctl daemon-reload
sudo systemctl start msh-zr-node.service msh-zr-milter.service

Web admin server (web admin)​

Update it after every MTA server runs the new version.

sudo systemctl stop msh-zr-web.service
sudo tar zxvf msh-zr-<VERSION>.tgz -C /opt --exclude='msh-zr/etc/*'
sudo sh /opt/msh-zr/lib/fixperms.sh
sudo systemctl daemon-reload
sudo systemctl start msh-zr-web.service

Description​

The steps are the same on every host; only the services differ. The single server commands are explained here.

Stop the services. From this point until the milter is started again, mail on this host is handled according to milter_default_action (see Mail flow during the update).

sudo systemctl stop msh-zr-web.service msh-zr-node.service msh-zr-milter.service

Unpack the new package over the existing tree, keeping the live etc/ directory as-is.

sudo tar zxvf msh-zr-<VERSION>.tgz -C /opt --exclude='msh-zr/etc/*'

Re-apply ownership and permissions.

sudo sh /opt/msh-zr/lib/fixperms.sh

Reload systemd to pick up any changes to the service unit files.

sudo systemctl daemon-reload

Start the services again. The order does not matter. If you switched milter_default_action to tempfail for the update, set it back to accept now.

sudo systemctl start msh-zr-node.service msh-zr-milter.service msh-zr-web.service

Verify​

Watch the logs to confirm a clean start:

journalctl -u msh-zr-node.service -u msh-zr-milter.service -u msh-zr-web.service -f

Then open the Servers page of the web admin. Every server must show the new version in the Version column and the state Up to date.

Mail flow during the update​

warning

While msh-zr-milter.service is stopped on a host, the Postfix on that host cannot reach the milter and falls back to milter_default_action. With the recommended accept (see Zimbra configuration) mail keeps flowing, but no rules are applied - messages arriving during the update are delivered without signatures, disclaimers, blocking or any other action, and nothing is logged about them. The window is usually only a few seconds, but if your rules matter for security (blocked senders, attachment filtering, quarantine), do not rely on it being empty.

Stopping the web admin or the node does not affect mail: the milter keeps working with the rules and settings it already has. Only the milter matters for mail flow, and only on the host it runs on. In a multi-server installation the other MTA servers keep filtering normally while one is being updated.

If unfiltered mail during the update is not acceptable, temporarily switch the default action of the host you are updating to tempfail. Postfix then answers every incoming message with 451 4.7.1 Service unavailable - try again later while the milter is down: sending mail servers keep the message in their own queue and retry (typically within 5-15 minutes), and locally injected mail stays in Zimbra's queue. Nothing is lost, only delayed. Users sending from the Zimbra web client during those seconds see the same 451 error and have to resend.

Before stopping the services, as the zimbra user on that host (sudo su - zimbra):

zmprov ms $(zmhostname) zimbraMtaMilterDefaultAction tempfail
zmmtactl reload

Wait until Postfix has picked up the change before you stop the milter - check with postconf milter_default_action until it reports tempfail.

After the update, once msh-zr-milter.service is running again, switch back:

zmprov ms $(zmhostname) zimbraMtaMilterDefaultAction accept
zmmtactl reload

Deferred messages are delivered as soon as the sending servers retry; run mailq on the Zimbra host to see anything still waiting locally.

info

Stopping the whole MTA instead (zmmtactl stop) also prevents unfiltered mail, but it additionally pauses outbound delivery and rejects connections at the TCP level, so tempfail is the less disruptive option.

Additional resources​