本文目錄
本文的對象是 Zimbra NE(Network Edition,商用版)主機。前一篇〈Zimbra OSE 從 Ubuntu 20.04 升級至 22.04〉整理了開源版的做法,這篇是商用版。
整體流程和開源版相同:備份設定、升級作業系統、用 22.04 版的安裝檔把同版本的 Zimbra 重新裝一次。不過商用版多了授權、ACL 與專屬的元件和套件來源,有幾個地方的做法剛好相反,照開源版的步驟直接做會出問題。
本文是我實際升級一台商用版正式主機的記錄。前半段是可以照順序做的步驟,後半段整理過程中遇到的問題。文中的終端機畫面依實際升級記錄重製,主機名稱、IP 與授權碼已替換為範例值。
適用範圍
| 項目 | 內容 |
|---|---|
| Zimbra | NE 商用版 10.1.21(核心套件 10.1.0 GA build 4633,UBUNTU20_64) |
| 作業系統 | Ubuntu 20.04 → 22.04 |
| 架構 | 單台部署,使用中的元件都在同一台,含 license daemon;未安裝 onlyoffice |
| 授權 | 線上啟用的授權碼,主機可連外 |
| 安裝檔 | zcs-NETWORK-10.1.0_GA_4655.UBUNTU22_64.20240819064312.tgz(Zimbra 官方) |
Zimbra Wiki 的 Ubuntu Upgrades 頁面寫明,20.04 升級至 22.04 只支援 ZCS 10.1.1 以上。多台主機的架構與離線授權的流程不同,不在本文範圍內。
本文流程的驗證程度
開源版的流程我先在測試機演練過,商用版這次沒有另外演練,是直接排維護時段,靠 VM 快照當退路升級正式主機,一次完成。
所以本文只代表我這一台的結果。條件允許的話,建議先複製一台測試機跑過一次,但有兩件事要先處理:
- 網路隔離
測試機要限制對外連線與 DNS,擋掉對正式主機與外部 SMTP 的連線,否則佇列裡的信可能真的寄出去 - 授權
Zimbra 的升級文件寫明一組授權碼只能用在一套環境,不能拿正式授權在複製機上啟用。官方提供獨立的實驗室授權,要向 Zimbra 申請
另外,Zimbra Wiki 的升級範例是設定 AllowThirdParty=yes,讓 Zimbra 的套件來源跟著作業系統升級。我沿用開源版驗證過的做法,升級前把來源註解掉,之後再啟用。Wiki 那個做法我沒有測試,不能保證兩者結果相同。
商用版與開源版的差異
| 項目 | 前篇的開源版(自行打包) | 本文的商用版 |
|---|---|---|
| 安裝檔 | 自行打包 | Zimbra 官方下載 |
Use Zimbra's package repository | N | Y |
| ACL | 前篇未處理 | 升級前 zmacl disable,完成後 zmacl enable |
| Zimbra 的 apt 來源 | 平常保持註解 | 平常保持啟用,patch 靠它更新 |
| 授權 | 無 | 使用授權碼,要確認重裝後仍然有效 |
| license daemon | 無 | 不歸 zmcontrol 管,要另外停止 |
另外要先了解商用版 10.1.x 的套件結構:核心套件是 10.1.0 GA,之後的 10.1.x 都是透過 apt 從官方套件庫安裝 patch 套件(zimbra-patch、zimbra-ldap-patch、zimbra-mta-patch、zimbra-proxy-patch 等)升上去的。
所以 zmcontrol -v 顯示 10.1.21,dpkg -l zimbra-core 顯示的卻是 10.1.0。重裝時用的是 10.1.0 GA 的 22.04 版安裝檔,patch 則由安裝程式從套件庫自動補回來。
作業系統升級對 Zimbra 的影響
do-release-upgrade 會發現 Zimbra 的套件依賴 20.04 專屬的函式庫,於是把它們列入移除清單。我的主機上是 52 個 Zimbra 核心套件加上 51 個 zimbra-perl 套件。
這些套件被移除後,我的主機上 /opt/zimbra/conf 少了一大半,localconfig.xml 也不見了。
不過資料都還在:郵件本體、MariaDB、LDAP、索引,以及 /opt/zimbra/.saveconfig、授權目錄 /opt/zimbra/license。
openssl、openjdk、postfix 這些第三方元件則不會被移除,會以 20.04 版的狀態留下來,安裝後要另外升級。
這時候如果直接執行 install.sh,它會把這台主機當成全新安裝。所以重點和開源版一樣:
- 升級前備份
/opt/zimbra/conf,升級後還原 - 執行
install.sh時加上--force-upgrade
升級前準備
維護時段
我的主機郵件資料約 17 GB,從停止 Zimbra 到服務全部恢復約 1 小時 50 分,其中作業系統升級約 45 分鐘、install.sh 約 45 分鐘。建議預留 2.5~3 小時。
升級期間 Webmail、收發信、手機同步都會中斷,請事先通知使用者。
VM 快照
務必在停止 Zimbra 後建立 VM 快照,這是本文主要的回復方式。建立前確認快照涵蓋所有資料磁碟,儲存空間也足夠。快照不等於備份,獨立的完整備份也要有。
作業系統升級做到一半失敗時,不要嘗試在半升級的狀態下修 Zimbra,直接回復快照再重來。
主機狀態
lsb_release -ds # Ubuntu 20.04.x LTS
df -h / /boot /opt # / 建議 10 GB 以上可用
locale -a | grep -i en_us # 要有 en_US.utf8,沒有的話先 locale-gen en_US.UTF-8
su - zimbra -c "zmcontrol -v"
su - zimbra -c "zmlicense -c" # Activation status: License is OK
apt update
apt list --upgradable 2>/dev/null | grep '^zimbra.*patch'
最後兩行是確認 Zimbra 的來源正常,而且目前的套件索引沒有列出可升級的 patch,apt update 有錯誤就要先處理。重裝時 patch 是從套件庫取得,如果主機上不是最新版,這次升級就會變成作業系統升級再加上 Zimbra 更新。建議停機前先更新到最新 patch 並確認正常;我的主機升級前後都是 10.1.21,沒有遇到版本不同的情況。
前端 MTA 的退信風險
如果這台主機前面還有其他 MTA(郵件閘道或另一台 Zimbra)會轉信給它,請確認那台在送不到這台主機時,是把信留在佇列重試,而不是轉給其他主機或直接退信。
特別注意 smtp_fallback_relay 這類設定,在 Zimbra 上對應的屬性是 zimbraMtaFallbackRelayHost。送不到時改走別的路,如果那條路回的是永久錯誤(5xx),信就會被退回。我的環境就是先把這個設定清掉才排升級的,停機期間的信最後全部補送成功。
下載安裝檔
商用版的安裝檔可以直接從 Zimbra 官方網站下載,不需要登入,授權另外啟用。注意官方網站上 22.04 版的 build 編號是 4655,和 20.04 版的 4633 不同:
mkdir -p /root/zcs-upgrade-u22 && cd /root/zcs-upgrade-u22
wget https://files.zimbra.com/downloads/10.1.0_GA/zcs-NETWORK-10.1.0_GA_4655.UBUNTU22_64.20240819064312.tgz
wget https://files.zimbra.com/downloads/10.1.0_GA/zcs-NETWORK-10.1.0_GA_4655.UBUNTU22_64.20240819064312.tgz.sha256
sha256sum -c zcs-NETWORK-10.1.0_GA_4655.UBUNTU22_64.20240819064312.tgz.sha256
tar xzf zcs-NETWORK-10.1.0_GA_4655.UBUNTU22_64.20240819064312.tgz
tmux
do-release-upgrade 和 install.sh 都要跑很久,中間又有很多題目要回答,請在 tmux 裡執行,避免 SSH 斷線造成升級中斷:
apt install -y tmux
tmux new -A -s upgrade
tmux 不會跨重新開機存活,重新開機登入後要再執行一次 tmux new -A -s upgrade。
文中有幾個指令會解析 apt 的英文輸出,主機不是英文語系的話,先執行 export LC_ALL=en_US.UTF-8。
步驟一:記錄現況與備份
Zimbra 還在執行時,先把現況記錄下來,升級完要拿來比對。
後面的步驟都會用到 BK 這個變數,如果中間重新登入或重新開機,記得再設定一次。這個目錄會存放明碼密碼與授權碼,權限設成只有 root 能讀:
BK=/root/pre-u22-backup
mkdir -p $BK && chmod 700 $BK
su - zimbra -c "zmcontrol -v; zmcontrol status" > $BK/pre-status.txt
su - zimbra -c "zmprov -l gaa" > $BK/pre-accounts.txt
su - zimbra -c "zmprov gad" > $BK/pre-domains.txt
su - zimbra -c "zmprov gs \$(zmhostname) zimbraServiceEnabled zimbraReverseProxySSLProtocols" > $BK/pre-keysettings.txt
su - zimbra -c "zmlocalconfig -s" > $BK/localconfig.txt
su - zimbra -c "zmlicense -c; zmlicense -p" > $BK/pre-license.txt 2>&1
dpkg -l > $BK/dpkg-l.txt
crontab -l > $BK/root-crontab.txt 2>/dev/null
crontab -u zimbra -l > $BK/zimbra-crontab.txt 2>/dev/null
pre-license.txt 裡有目前的授權碼,萬一重裝後授權有問題,會用到它。
記下目前安裝了哪些 Zimbra 元件,步驟五回答問題時要對照:
for p in zimbra-ldap zimbra-logger zimbra-mta zimbra-dnscache zimbra-snmp zimbra-store \
zimbra-apache zimbra-spell zimbra-memcached zimbra-proxy zimbra-convertd zimbra-archiving \
zimbra-onlyoffice zimbra-license-daemon zimbra-license-tools zimbra-modern-ui zimbra-patch; do
printf "%-22s %s\n" $p "$(dpkg-query -W -f='${Status} ${Version}' $p 2>/dev/null || echo not-installed)"
done | tee $BK/zimbra-components.txt
匯出 LDAP。不要放在 /root 底下,zimbra 帳號寫不進去:
L=/var/backups/zimbra-pre-u22
mkdir -p $L && chown zimbra:zimbra $L && chmod 700 $L
su - zimbra -c "/opt/zimbra/libexec/zmslapcat $L && /opt/zimbra/libexec/zmslapcat -c $L"
ls -la $L
要看到 ldap.bak 和 ldap-config.bak 兩個不是空的檔案。
備份 /opt/zimbra/conf、.saveconfig 和授權目錄:
tar czpf $BK/zimbra-conf.tgz -C /opt/zimbra conf
tar czpf $BK/zimbra-saveconfig-original.tgz -C /opt/zimbra .saveconfig
tar czpf $BK/zimbra-license.tgz -C /opt/zimbra license
商用版 10.1 的授權狀態存在 /opt/zimbra/license/store/ 底下。我的主機升級後這個目錄還在,但它所屬的套件在升級時會被移除,所以一併備份。
確認 .saveconfig 裡的 localconfig.xml 和目前使用中的一致。install.sh 在套件裝完、執行 zmsetup 之前,會用 .saveconfig 還原 localconfig.xml、keystore 與服務憑證:
cmp /opt/zimbra/.saveconfig/localconfig.xml /opt/zimbra/conf/localconfig.xml \
&& echo 一致 || { cp -p /opt/zimbra/conf/localconfig.xml /opt/zimbra/.saveconfig/ && echo 已更新; }
商用版如果長期只靠 patch 升級,.saveconfig 會是很久以前最後一次執行 install.sh 留下的,我的主機上就是一年多前的版本,這一步一定要做。前面的 zimbra-saveconfig-original.tgz 是更新前的原樣,只留作對照,不要拿來還原。
最後看一下有哪些已安裝、但目前的套件來源找不到的套件,手動安裝的 .deb(記錄轉送、監控 agent 等)多半會列在這裡,升級後要確認它們的狀態:
apt list --installed 2>/dev/null | grep '\[installed,local\]'
這份清單只代表該版本目前的來源下載不到,不能完整盤點第三方軟體,還是要對照主機上實際執行的服務。
步驟二:停止 Zimbra、停用 ACL、建立快照、整理 apt 來源
su - zimbra -c "zmcontrol stop"
su - zimbra -c "zmlicensectl --service stop"
ps -u zimbra -o pid,args --no-headers
注意,license daemon 不歸 zmcontrol 管,停止 Zimbra 之後它還會繼續執行,要另外停止。zmlicensectl 要用 zimbra 身分執行,用 root 會出現 must be run as zimbra user。
確認只剩 zimbra 帳號的登入 shell 之類的程序後,用 root 停用 ACL:
/opt/zimbra/bin/zmacl disable
要看到 ACLs removed successfully。Zimbra Wiki 的升級範例寫明,NE 10.1.6 以上要先停用 ACL,升級完再啟用。從 zmacl 的原始碼可以看到,它處理的是 /opt/zimbra/jetty/webapps 的寫入權限,停用後目錄擁有者可以寫入。

這時候建立 VM 快照。
接著停用開機自動啟動,避免升級後重新開機時,用已經被刪掉一半的 20.04 程式啟動:
systemctl disable zimbra
把 Zimbra 的 apt 來源全部註解掉。商用版的來源可能分在不只一個檔案裡,我的 onlyoffice 就是獨立的 zimbra-onlyoffice.list:
ls /etc/apt/sources.list.d/ | grep -i zimbra
cp -p /etc/apt/sources.list.d/zimbra*.list $BK/
sed -i -E 's/^(deb|deb-src) /#\1 /' /etc/apt/sources.list.d/zimbra*.list
grep -hE '^(deb|deb-src) ' /etc/apt/sources.list.d/zimbra*.list || echo 已全部註解
補齊 20.04 的更新,do-release-upgrade 要求系統是最新狀態:
apt update
apt upgrade -y
如果更新到核心(有 /var/run/reboot-required),請先重新開機一次再繼續。apt upgrade 不會為了升級而移除套件,如果 do-release-upgrade 回報還有更新沒裝,先用 apt list --upgradable 看是哪些,確認移除清單沒有問題再處理。
步驟三:升級作業系統
do-release-upgrade
| 題目 | 回答 |
|---|---|
Continue running under SSH? | y |
Starting additional sshd on port 1022 | Enter |
Do you want to start the upgrade? | y |
Restart services during package upgrades without asking? | Yes |
Services to restart for GNU libc library upgrade | Ok |
設定檔衝突(*** xxx (Y/I/N/O/D/Z) [default=N] ?) | N(保留現有版本) |
| 設定檔衝突的對話框(例如 sshd_config) | keep the local version currently installed |
Remove obsolete packages? | N |
System upgrade is complete. Restart required | y |
我遇到的設定檔衝突有 crontab、sysctl.conf、sshd_config、snmpd.conf,一律保留現有版本。保留舊設定不代表它和新版完全相容,重新開機前先另開一個連線執行 sshd -t 檢查 SSH 設定,並準備好 VM 主控台,其他設定事後再比對新版的差異。


重新開機後確認:
lsb_release -ds # Ubuntu 22.04.x LTS
systemctl is-enabled zimbra # disabled
ls /opt/zimbra/conf/localconfig.xml # 預期:No such file or directory
步驟四:還原設定檔、啟用 22.04 的 apt 來源
tmux new -A -s upgrade
BK=/root/pre-u22-backup
tar xzpf $BK/zimbra-conf.tgz -C /opt/zimbra
ls -la /opt/zimbra/conf/localconfig.xml
接著把 Zimbra 的 apt 來源改成 22.04 並啟用。先看一下檔案現在的內容:
cat /etc/apt/sources.list.d/zimbra*.list
我的主機上 do-release-upgrade 已經自己把 focal 改成 jammy,只是格式變成 # deb ...(# 後面多一個空格)。用下面的指令啟用,deb-src 維持註解:
sed -i -E 's/^#\s*deb\s+\[/deb [/; s/ focal / jammy /' /etc/apt/sources.list.d/zimbra*.list
grep -hE '^deb ' /etc/apt/sources.list.d/zimbra*.list
apt update
確認 22.04 版的套件都找得到:
for p in zimbra-openssl zimbra-patch zimbra-license-daemon; do
echo "$p: $(apt-cache policy $p | grep Candidate)"
done
Candidate 都要是 .22.04 或 .u22 結尾。如果還是 20.04 版,先確認來源行都有啟用:上面的 sed 是對應 [arch=amd64] 這種寫法,來源行沒有方括號的要自行調整。
再檢查有沒有 /etc/apt/preferences.d/zimbra,處理方式見開源版那篇的步驟四;我這台商用版主機沒有這個檔案。

步驟五:執行 install.sh --force-upgrade
cd /root/zcs-upgrade-u22/zcs-NETWORK-10.1.0_GA_4655.UBUNTU22_64.20240819064312
./install.sh --force-upgrade
注意,--force-upgrade 不能漏掉。套件已經被移除了,install.sh 自己判斷不出這是升級。另外,線上授權不要加 --skip-activation-check,Zimbra 的升級文件也這樣提醒。
| 題目 | 回答 |
|---|---|
Do you agree with the terms of the software license agreement? | y |
Use Zimbra's package repository | Y(和開源版相反) |
Do you wish to upgrade? | Y |
Install zimbra-xxx [N](逐一詢問) | 對照 zimbra-components.txt:有安裝的答 y,沒安裝的答 N |
確認 Installing: 清單 | 和 zimbra-components.txt 比對,不能少 |
The system will be modified. Continue? | y |
Port conflicts detected! - Press Enter/Return key to continue | 先另開視窗用 ss -lntup 查明佔用的程序,確認原因再按 Enter |
Configuration complete - press return to exit | Enter |
Use Zimbra's package repository 一定要答 Y

license-daemon、modern-ui 和 10.1.x 的 patch 套件都在商用版的套件庫裡。答 Y 之後,Installing: 清單會自動包含這些套件,例如:
zimbra-license-daemon
zimbra-modern-ui
zimbra-patch
zimbra-mta-patch
zimbra-proxy-patch
zimbra-ldap-patch
zimbra-lds-patch
Install zimbra-xxx 預設值是 N
和開源版一樣,每一題的預設值都是 N,一路按 Enter 就會漏裝元件。商用版會多問 convertd、archiving、onlyoffice,原本沒安裝的(例如我的 onlyoffice)就答 N。
即使之前停用了 snmp 或 spell 服務,套件本身還是要裝回去。
license-daemon 在我的主機上是直接顯示 Upgrading zimbra-license-daemon,沒有另外詢問。Zimbra 的升級文件寫明單台主機必須安裝這個元件,如果畫面有問,一定要答 y。

出現 Would you like to delete /opt/zimbra before installing?
代表 --force-upgrade 沒有生效。這題答 N,然後按 Ctrl+C 中止,回頭確認指令。
過程中會看到的訊息
Running mysql_upgrade...
MariaDB 的升級檢查Updating zimbraLDAPSchemaVersion、Upgrade complete.
LDAP schema 更新與升級模式完成,代表 zmsetup 走的是升級流程Activating license...license successfully activated.
安裝程式自動重新啟用授權Unable to start TLS: ... certificate verify failed when connecting to ldap master
如果換過憑證,這裡可能會出現。我的主機安裝程式有繼續跑完,再到步驟六處理;如果設定步驟因此中止,先停下來查明,不要直接往下做
另外,我這次安裝過程沒有出現開源版的 Notify Zimbra of your installation? 這題。


步驟六:安裝後修正
有使用商用憑證的主機:重新部署憑證
install.sh 會從 .saveconfig 還原 LDAP、nginx、postfix 用的憑證與 keystore。如果 .saveconfig 是很久以前的,還原回來的就是舊憑證,甚至已經過期。
C=/opt/zimbra/ssl/zimbra/commercial
/opt/zimbra/common/bin/openssl x509 -in $C/commercial.crt -noout -enddate -fingerprint -sha256
/opt/zimbra/common/bin/openssl x509 -in /opt/zimbra/conf/slapd.crt -noout -enddate -fingerprint -sha256
兩邊的指紋不同,就重新部署現行的商用憑證:
su - zimbra -c "/opt/zimbra/bin/zmcertmgr deploycrt comm $C/commercial.crt $C/commercial_ca.crt"
deploycrt 會檢查私密金鑰與憑證鏈,部署後要重新啟動服務才會生效,下一節的停止與啟動會一起處理。啟動後務必用 zmcertmgr viewdeployedcrt 確認各服務的憑證期限與主機名稱,並實際連線測試。
使用自我簽署憑證的主機沒有 commercial.crt,但 .saveconfig 一樣會把舊憑證還原回來,也要檢查。

把剩下的第三方元件升級成 22.04 版
install.sh 不會把全部套件都換掉,還會有一批 Zimbra 第三方套件停在 20.04 的建置版本。這些套件大多版本號一樣,只是為 22.04 重新編譯,但舊版裡面的 Perl 模組是給 20.04 的 Perl 用的,放著不管會影響 logger 這類服務。
先列清單並模擬。這份清單是所有可升級的 Zimbra 套件,也可能包含真正的版本更新:
dpkg-query -W -f='${Version}\n' 'zimbra*' | grep -c '20\.04'
apt list --upgradable 2>/dev/null | grep '^zimbra' | cut -d/ -f1 > $BK/zimbra-u20-leftover.txt
apt-get install -s --only-upgrade $(cat $BK/zimbra-u20-leftover.txt) | grep 'upgraded,'
模擬要看到 0 to remove。如果有套件要移除或新增,拿掉 grep 看完整結果,每一項都確認過再繼續。接著實際升級,同時讓新憑證生效:
su - zimbra -c "zmcontrol stop"
apt-get install -y --only-upgrade $(cat $BK/zimbra-u20-leftover.txt)
/opt/zimbra/libexec/zmfixperms
su - zimbra -c "zmcontrol start"
dpkg-query -W -f='${Version}\n' 'zimbra*' | grep -c '20\.04' # 要是 0
我的主機上版本含 20.04 的有 73 個,可升級的清單是 74 個,全部升級後 20.04 版為 0。zmcontrol 不管 license daemon,這批套件如果包含 zimbra-openjdk 或 license daemon 相關套件,完成後要用 zimbra 身分執行 zmlicensectl --service restart,再確認授權。
最後確認已安裝的 Zimbra 套件都沒有舊平台的版本,patch 也都是 22.04 版:
dpkg-query -W -f='${db:Status-Status} ${Package} ${Version}\n' 'zimbra*' \
| awk '$1=="installed"' | grep -E '20\.04|\.u20|UBUNTU20' || echo 沒有舊平台套件
dpkg-query -W -f='${Package} ${Version}\n' 'zimbra*patch'

步驟七:驗證
驗證完成前先不要對使用者開放。注意 systemctl disable zimbra 擋不住安裝程式,install.sh 會自己啟動服務,前端 MTA 也可能開始送信。要完全擋住,就要在防火牆或反向代理限制連線,保留管理連線,直到驗證完成。
版本、服務與授權
su - zimbra -c "zmcontrol -v"
su - zimbra -c "zmcontrol status"
su - zimbra -c "zmlicense -c"
- 版本:
Release 10.1.x.GA.4655.UBUNTU22_64 NETWORK edition. - 服務清單和
$BK/pre-status.txt相同、全部 Running - 授權:
Activation status: License is OK

如果 antivirus 顯示 Stopped,先看 /opt/zimbra/log/clamd.log,clamd 剛啟動要載入病毒碼,可能要等十幾分鐘。
如果授權不是 License is OK,先保存錯誤訊息,確認主機可以連外,再依 Zimbra 的授權問題文件判斷原因。步驟一備份的 zimbra-license.tgz 這次沒有用到,還原它是否有效我沒有驗證過,不要當成標準做法。
帳號、網域、設定
su - zimbra -c "zmprov -l gaa" | sort | diff - <(sort $BK/pre-accounts.txt) && echo 帳號一致
su - zimbra -c "zmprov gad" | sort | diff - <(sort $BK/pre-domains.txt) && echo 網域一致
su - zimbra -c "zmlocalconfig -s" | diff - $BK/localconfig.txt && echo 設定一致
su - zimbra -c "zmprov gs \$(zmhostname) zimbraServiceEnabled zimbraReverseProxySSLProtocols" | sort \
| diff - <(sort $BK/pre-keysettings.txt) && echo 服務設定一致
比對前先確認備份的檔案不是空的。最後一項同時包含服務清單與 TLS 設定,差異要逐項看。我的差異是之前手動停用的 snmp、spell 被安裝程式加回去了,所以重新停用;下面的指令請換成自己環境實際多出來的服務:
su - zimbra -c "zmprov ms \$(zmhostname) -zimbraServiceEnabled snmp -zimbraServiceEnabled spell"
su - zimbra -c "zmspellctl stop; zmswatchctl stop"
排程
zimbra 帳號的 crontab 裡,指定註解區間內的項目會被新版預設值覆蓋,區間外的自訂項目會保留。用步驟一存的 zimbra-crontab.txt 比對,不要直接蓋回舊檔。
實際使用
- 登入 Webmail,確認信件、行事曆、聯絡人都在
- 內外部收發信各測試一封
- 手機 ActiveSync 同步測試
- 如果前面還有其他 MTA,確認它佇列裡停機期間的信已經送進來(
postqueue -p,必要時postqueue -f)
步驟八:收尾
重新啟用 ACL
/opt/zimbra/bin/zmacl enable
getfacl -p /opt/zimbra/jetty/webapps | head -5
要看到 ACLs applied successfully,getfacl 的 user:zimbra 是 r-x,沒有 w。zmacl 不會逐項檢查指令結果,所以成功訊息之外還要看實際權限。
ACL 不是只有這裡會套用。Zimbra 10.1.6 的發行說明提到,重新啟動服務、更新 patch、執行 zmfixperms 都可能重新套用;我主機上的 zmfixperms 結尾就會執行 zmacl enable,所以步驟六之後多半已經生效,這裡是再執行一次並確認。

開機自動啟動與 apt 來源
確認開機自動啟動。install.sh 通常會改回 enabled,不是的話用 systemctl enable zimbra 打開:
systemctl is-enabled zimbra
Zimbra 的 apt 來源:商用版平常就是靠這些來源更新 patch,維持 jammy 啟用即可,不用像開源版那樣註解回去。
第三方套件
確認步驟一記下的第三方套件。依賴 20.04 函式庫的套件,可能因為步驟三答了不移除過時套件而暫時還能執行,但之後清理過時套件時就會壞掉,建議趁這次換成 22.04 可用的版本或替代工具。
刪除快照與備份
確認沒問題、觀察幾天之後,再刪除步驟二建立的 VM 快照。
$BK 裡的 localconfig.txt 有明碼密碼、pre-license.txt 有授權碼,/var/backups/zimbra-pre-u22 是完整的 LDAP 資料(含密碼雜湊),觀察期過後一併刪除,或移到受控的備份位置。
回復方式
升級失敗時,回復步驟二建立的 VM 快照,開機後確認:
lsb_release -ds
su - zimbra -c "zmcontrol -v"
su - zimbra -c "zmlicense -c"
快照是在停用開機自動啟動之前建立的,不含記憶體的快照回復後開機,Zimbra 會照常啟動。快照是在停用 ACL 之後建立的,回復後用 getfacl 確認,必要時執行 /opt/zimbra/bin/zmacl enable。
注意,直接回復快照只適用於還沒有正式寫入的階段。如果已經收過新信或使用者改過資料,連驗證時的測試資料在內,回復後這些內容都會消失,前端 MTA 也不會重送已經成功投遞的信,要先保存再規劃補回。
實際遇到的問題與解法
license daemon 未隨 zmcontrol 停止
zmcontrol stop 之後,用 ps -u zimbra 檢查還有一支 java 程序在執行,是 license daemon。要用 zimbra 身分執行 zmlicensectl --service stop 另外停止(步驟二)。
onlyoffice 的套件來源在獨立檔案
註解 zimbra.list 之後,才發現 onlyoffice 的來源在另一個檔案 zimbra-onlyoffice.list。處理 apt 來源時用 zimbra*.list 一次涵蓋所有檔案,處理前先列出目錄確認。
apt 來源格式被改寫
照開源版的做法用 s/^#(deb\s)/\1/ 把來源打開,結果一行都沒有啟用,apt-cache policy 的 Candidate 還是 20.04 版。
原因是 do-release-upgrade 已經把這些已註解的行改寫成 # deb [arch=amd64] ... jammy zimbra,# 後面多了一個空格。要改用能容許空格的寫法(步驟四)。
LDAP 的 TLS 驗證失敗
安裝過程中出現:
Unable to start TLS: SSL connect attempt failed error:0A000086:SSL routines::certificate verify failed when connecting to ldap master.
原因是 --force-upgrade 從 .saveconfig 還原了舊憑證。我的主機上次完整執行 install.sh 是一年多前,.saveconfig 裡的憑證早就過期了,而實際在用的商用憑證是後來換的新憑證。安裝完成後重新部署現行憑證,再重新啟動服務即可(步驟六)。
snmp 與 spell 服務被重新啟用
驗證時發現 zimbraServiceEnabled 多了 snmp 和 spell,這兩個是我之前手動停用的,安裝程式會把它們加回去。重新停用並停止對應的程序(步驟七)。
.saveconfig 的 localconfig 版本過舊
cmp 比對時發現 .saveconfig/localconfig.xml 和目前使用中的不一樣。install.sh 在執行 zmsetup 之前會用它覆蓋回去,不處理的話,還原回來的就是一年前的設定。升級前先把目前的 localconfig.xml 複製過去(步驟一)。
停機期間的來信退回
這台主機前面還有一台 MTA 負責轉信給它。那台 MTA 原本設定了 fallback relay,送不到這台主機時會改走郵件閘道,而郵件閘道對這種信會回永久錯誤,信就被退回了。之前這台主機只重新開機幾分鐘,就退過信。
升級前我把那台 MTA 的 fallback relay 清掉,讓它送不到時把信留在自己的佇列重試。這次停機近兩個小時,期間寄來的 12 封信在恢復後全部補送進來,沒有任何一封被退回。
依賴 20.04 函式庫的記錄轉送程式
主機上有一套手動安裝的記錄轉送程式,依賴 20.04 的 Perl、Python、libssl1.1。升級後它還在執行,原因是 Remove obsolete packages 答了 N,那些舊函式庫還留在系統上。
這種狀態以後清理過時套件時就會壞,所以我趁這次換成支援 22.04 的工具,用相同的設定重新接上。
結論
商用版的升級,主體和開源版一樣:備份並還原 /opt/zimbra/conf、install.sh 加上 --force-upgrade、Install zimbra-xxx 原本有的都答 y、安裝後重新部署憑證、補升 20.04 殘留的套件。
商用版另外要注意的是:
- 用官方 22.04 版安裝檔(build 4655),套件庫那題答 Y
- 升級前
zmacl disable,完成後zmacl enable - license daemon 要另外停止,授權狀態目錄要備份
- apt 來源可能分在好幾個檔案,作業系統升級後格式也會被改寫
- 收尾後 Zimbra 的 apt 來源維持啟用
我這台主機升級後,帳號、網域、設定、授權都有延續下來,patch 也由安裝程式補回 22.04 版。商用版這次沒有先演練,如果環境允許,還是建議先用複製的測試機跑過一次。
參考資料
- Zimbra Wiki:Ubuntu Upgrade Example
https://wiki.zimbra.com/wiki/AGibanelBtactic-Ubuntu-Upgrade-Example - Zimbra Wiki:Ubuntu Upgrades
https://wiki.zimbra.com/wiki/Ubuntu_Upgrades - Zimbra 10.1.6 發行說明
https://wiki.zimbra.com/wiki/Zimbra_Releases/10.1.6 zmacl原始碼
https://github.com/Zimbra/zm-core-utils/blob/develop/src/bin/zmacl- Zimbra 10 升級文件
https://zimbra.github.io/documentation/zimbra-10/upgrade.html - Zimbra 授權問題排除
https://zdocs.github.io/KB/nftf/Troubleshoot%20License%20Errors.html - Zimbra Collaboration 商用版下載
https://www.zimbra.com/product/download/zimbra-collaboration-network-edition/ - Zimbra OSE 從 Ubuntu 20.04 升級至 22.04
https://blog.jason.tools/2026/10/zimbra-ubuntu-2204-upgrade.html



