跳到主要內容
節省工具箱Jason Tools
經驗分享

PMG 轉信 Zimbra 的 SMTPUTF8 退信處理

Jason Cheng 發布 瀏覽 1 次
PMG 轉信 Zimbra 的 SMTPUTF8 退信處理
本文目錄
  1. 錯誤訊息
  2. SMTPUTF8 是什麼
  3. 為什麼只有部分信件被退
  4. 確認下一站是否支援 SMTPUTF8
  5. 處理方式:在 PMG 停用 SMTPUTF8
  6. 停用後的影響
  7. 結論
  8. 參考資料

實際案例:某客戶的架構是 PMG(Proxmox Mail Gateway)放在前端過濾垃圾郵件,再把信轉交給內部的 Zimbra。某天開始陸續有使用者反應,部分外部寄來的信收不到,寄件者那邊收到退信通知。

到 PMG 查郵件記錄,退信原因都是同一句:SMTPUTF8 is required, but was not offered by host。這篇整理這個錯誤的成因、為什麼只有部分信件會被退,以及在 PMG 上正確的處理方式。

錯誤訊息

在 PMG 的 /var/log/mail.log(或網頁介面的「追蹤中心」)可以看到類似這樣的記錄:

Mar 27 10:15:32 pmg postfix/smtp[12345]: 4ABCD1234567: to=<user@example.com>, relay=mail.example.com[192.168.1.20]:25, delay=0.35, delays=0.1/0/0.2/0, dsn=5.6.7, status=bounced (SMTPUTF8 is required, but was not offered by host mail.example.com[192.168.1.20])

relay= 後面是 PMG 要轉交的下一站,也就是內部的 Zimbra。意思是:這封信需要 SMTPUTF8,但 Zimbra 沒有宣告支援,所以 PMG 直接退信。

較新版的 Postfix 把這段訊息改寫成 message requires SMTPUTF8, but no server was found that supports SMTPUTF8,意思相同,狀態碼一樣是 5.6.7。

SMTPUTF8 是什麼

SMTPUTF8 是 RFC 6531 定義的 SMTP 擴充功能,屬於 EAI(Email Address Internationalization,郵件地址國際化)的一部分,讓郵件地址與表頭可以直接使用 UTF-8,例如中文的帳號或網域名稱。

運作方式是:

  • 收件伺服器在 EHLO 回應中列出 SMTPUTF8,表示支援
  • 寄件端在 MAIL FROM 指令後面加上 SMTPUTF8 參數,表示這封信需要 UTF-8 處理

Postfix 3.0 起內建 SMTPUTF8 支援,smtputf8_enable 預設是 yes。PMG 底層就是 Postfix,所以 PMG 預設也是開啟的。

為什麼只有部分信件被退

依 Postfix 官方文件(SMTPUTF8_README),當 Postfix 收到一封帶有 SMTPUTF8 要求的信,要轉交給不支援 SMTPUTF8 的下一站時,只有在下列條件都成立時才會照常投遞:

  • 所有表頭的值都沒有 UTF-8
  • 信封寄件者地址沒有 UTF-8
  • 這次投遞的信封收件者地址沒有 UTF-8

只要有一項不符合,就會把信退回。整個流程是:

  1. PMG 在 EHLO 回應中宣告支援 SMTPUTF8
  2. 外部寄件伺服器(例如 Gmail)看到後,寄信時帶上 SMTPUTF8 要求
  3. 這封信的表頭裡有未經編碼的 UTF-8 文字,例如中文的寄件者名稱或主旨
  4. PMG 過濾完要轉交給 Zimbra,但 Zimbra 的 EHLO 回應沒有 SMTPUTF8
  5. 依上面的規則,PMG 只能退信

所以同一個寄件者,有些信正常、有些被退,差別就在寄件端有沒有帶 SMTPUTF8 要求、表頭裡有沒有 UTF-8。這也是這個問題容易被忽略的原因:大部分信件都正常,只有零星的退信。

確認下一站是否支援 SMTPUTF8

從 PMG 連到 Zimbra 的 25 埠,送出 EHLO 看回應:

telnet 192.168.1.20 25
220 mail.example.com ESMTP Postfix
EHLO pmg.example.com
250-mail.example.com
250-PIPELINING
250-SIZE 52428800
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

清單裡沒有 SMTPUTF8,就是不支援。輸入 QUIT 離開。

Zimbra 的 MTA 雖然也是 Postfix,但並不支援 SMTPUTF8,在 Zimbra 端開啟也無法解決(Zimbra 論壇有使用者試過,改了設定仍無效)。Proxmox 開發團隊在讓這個選項可以調整的修補說明裡,也直接列出 Zimbra、OpenXchange、MS Exchange 是常見不支援 SMTPUTF8 的下游伺服器。

處理方式:在 PMG 停用 SMTPUTF8

既然下游不支援,就讓 PMG 也不要宣告支援。PMG 不宣告 SMTPUTF8 之後,寄件端就不會帶 SMTPUTF8 要求,會改用傳統方式寄送(表頭以 RFC 2047 編碼),PMG 轉給 Zimbra 時也就不會再被擋下。

PMG 7.3 以後:用 pmgsh 設定

PMG 7.3 起,SMTPUTF8 是 PMG 本身的設定項目(/etc/pmg/pmg.conf 的 mail 區段 smtputf8),可以用 pmgsh 修改:

# 查看目前設定
pmgsh get /config/mail

# 停用 SMTPUTF8
pmgsh set /config/mail -smtputf8 0

透過 API 修改設定時,PMG 會自動重新產生 Postfix 設定檔並重新啟動服務,不需要另外執行其他指令。這個選項目前網頁介面上沒有,要用指令設定。

叢集環境在主節點設定即可,設定會同步到其他節點。

確認 Postfix 已經套用:

postconf smtputf8_enable

輸出 smtputf8_enable = no 就完成了。

為什麼不直接用 postconf -e

網路上常見的做法是:

postconf -e 'smtputf8_enable=no'
systemctl restart postfix

這樣當下確實有效,但 PMG 的 Postfix 設定檔 /etc/postfix/main.cf 是由範本產生的。之後只要在網頁介面改任何設定、更新套件,或執行 pmgconfig sync,main.cf 就會依範本重新產生,手動加的這一行會消失,問題又會回來,而且通常是過了一段時間才發生,很難聯想到原因。

注意:PMG 上的 Postfix 設定請勿直接修改 main.cf,要用 PMG 的設定項目或自訂範本。

PMG 7.3 以前:使用自訂範本

舊版 PMG 沒有 smtputf8 這個設定項目,要改用自訂範本。依 PMG 管理手冊,預設範本在 /var/lib/pmg/templates/,請勿直接修改,要複製到 /etc/pmg/templates/ 再改:

cp /var/lib/pmg/templates/main.cf.in /etc/pmg/templates/main.cf.in

在 /etc/pmg/templates/main.cf.in 加入一行:

smtputf8_enable = no

重新產生設定檔並重新啟動服務:

pmgconfig sync --restart 1

自訂範本會跟著叢集同步到其他節點。之後升級到 7.3 以上,建議改用 pmgsh 的設定,並把自訂範本移除,以免日後 PMG 更新範本內容時,自訂範本沒有跟著更新。

停用後的影響

  • 已經退回的信不會自動重送,要請寄件者重新寄一次
  • PMG 不再接受非 ASCII 的郵件地址,例如帳號是中文的 EAI 地址。目前台灣的企業與一般使用者幾乎沒有在用這類地址,影響很小
  • 中文主旨、中文寄件者名稱、中文附件檔名都不受影響,這些本來就可以用傳統的編碼方式傳送

結論

PMG 預設開啟 SMTPUTF8 本身沒有問題,問題在於前後兩站的能力不一致:前端宣告支援,下游卻不支援,中間的 PMG 只能退信。PMG 放在 Zimbra、Exchange 前面的架構,建議在 PMG 停用 SMTPUTF8,讓整條郵件路徑的能力一致。

修改時記得用 PMG 自己的設定方式,直接改 main.cf 遲早會被覆蓋。

參考資料

Jason Cheng

Jason Cheng

企業開源技術顧問,專注架構規劃與實務導入

關於作者 →

延伸閱讀