【Mail Server 系列文:第 6 篇】
SpamAssassin(SA)是郵件防護中最重要的 Anti-Spam 引擎。
在本系列中,我們採用 SpamAssassin 4.0 + MySQL(Bayes + TxRep)+ Amavis + Remote Learn(透過 Dovecot IMAPSieve) 的架構,使整體防垃圾信能力達到商用等級。
本篇將完整說明:
- 為什麼不要再使用本地 Bayes(~/.spamassassin)
- 為什麼推薦 SQL Bayes + TxRep
- 如何讓 SA 自動每日更新規則(sa-update / sa-compile)
- 如何透過 Dovecot 的 IMAPSieve 實作「移動郵件 → 自動 Learn」
- SpamAssassin Docker 化部署流程
- MySQL schema 調整與注意事項
- 與 Amavis 的整合要點(Inbound/Outbound)
本篇內容非常實務,能夠直接運作在你的 Mail Server 架構中。
1. SpamAssassin 4.0 架構概觀
你的 SA 架構如下:
Dovecot IMAPSieve
↓ 移動郵件
sa-remote-learn (spamc)
↓ 走 TCP(783)
SpamAssassin Docker
↓ SQL connect
MariaDB (Bayes + TxRep)
SpamAssassin 不直接由 Postfix 呼叫,而是由:
- Amavis → SpamAssassin(spamc/spamd 模式)
- Dovecot → Remote learn(spamc -L spam / ham)
如此設計:
✔ 避免 Postfix 直接卡在 content filtering
✔ SA 運算壓力可獨立負載
✔ MySQL Bayes/TxRep 可跨使用者共享
✔ SPAM/HAM 學習可由使用者自己透過 Webmail 移動郵件完成
2. 為什麼推薦 SQL Bayes + TxRep?
在舊式 SA 架構中:
- Bayes 學習儲存在
/var/lib/spamassassin或使用者目錄中 - TxRep(舊 AWL)儲存在本地 Berkeley DB
缺點:
✘ 多使用者無法共用學習
✘ 容器化後容易遺失
✘ 容器重建時需要手動備份
因此本架構採用:
✔ MySQL 儲存 Bayes
bayes_tokenbayes_varsbayes_seen
✔ MySQL 儲存 TxRep(白名單/黑名單評分)
txreptable
好處:
✔ 學習永久化
✔ 容器重建不受影響
✔ 讓 SpamAssassin 更「集中式智慧」
✔ 多使用者共享評分資料
3. SpamAssassin 的 Docker 建置流程
你建立了 SA 專用容器:
docker run -d --name spamassassin \
--network intranet-net \
-e MYSQL_EXTRA_FILE=/run/secrets/sa_mysql.cnf \
-e MYSQL_DB=sa40 \
-e ALLOW_NETS='172.18.0.0/16' \
-e ALLOW_USER_RULES=1 \
-e SA_COMPILE_ON_START=1 \
...
容器內掛載:
/etc/spamassassin → 設定檔(local.cf 等)
/var/lib/spamassassin → Bayes 資料(容器外部掛載)
/run/secrets → MySQL 密碼
你也把官方 rules 都複製出來後再掛回去,改善更新的持久性。
4. local.cf:Bayes + TxRep 完整設定
你的 local.cf 最終版:
use_bayes 1
bayes_auto_learn 0
bayes_store_module Mail::SpamAssassin::BayesStore::MySQL
bayes_sql_dsn DBI:mysql:database=sa40;host=maildb;port=3306
bayes_sql_username sa40
bayes_sql_password sa90452
loadplugin Mail::SpamAssassin::Plugin::TxRep
txrep_factory Mail::SpamAssassin::SQLBasedAddrList
user_awl_dsn DBI:mysql:database=sa40;host=maildb;port=3306
user_awl_sql_username sa40
user_awl_sql_password sa90452
user_awl_sql_table txrep
亮點:
✔ Bayes + TxRep 全部 SQL 化
✔ Bayes 自動學習關閉(因為你使用 IMAPSieve)
✔ TxRep 取代舊 AWL
5. Remote Learning:使用者移動郵件 → 自動學習
你使用 IMAPSieve + pipe filter:
- 移到 Junk → spam
- 移回 Inbox → ham
Sieve 規則:
learn-spam.sieve:
require ["vnd.dovecot.pipe", "copy", "imapsieve","environment", "variables"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-remote-learn-spam.sh" ["${username}"];
learn-ham.sieve:
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-remote-learn-ham.sh" ["${username}"];
shell 腳本透過 spamc:
/usr/bin/spamc -d spamassassin -p 783 -u "$SA_USER" -L spam
如此:
✔ 使用者自行操作即可進行 SPAM/HAM 學習
✔ Webmail Roundcube 與手機 App 都能觸發學習
✔ 全自動化、準確率更高
6. 每日自動更新規則:sa-update + sa-compile
你的 Amavis 容器負責每日更新 SA:
entrypoint.sh:
${CRON_MIN} ${CRON_HOUR} * * * root sa-update ${do_compile:+&& sa-compile} && pkill -HUP -f amavisd
優點:
✔ SA 規則每日自動更新
✔ compile 後執行效能提升 30–50%
✔ Amavis 重新讀入(HUP)即可套用新規則
7. Amavis 與 SpamAssassin 的整合
區分 2 個流程:
(1) Inbound
Postfix → Amavis → SpamAssassin → clean/spam → 回到 Postfix → Dovecot
(2) Outbound
User → Dovecot SASL → Postfix submission → Amavis (簽 DKIM + scan) → Internet
關鍵參數:
$sa_tag_level_deflt = 2.0;
$sa_tag2_level_deflt = 6.2;
$sa_kill_level_deflt = 6.9;
$final_spam_destiny = D_PASS; # 你目前選擇放行
你使用 D_PASS,代表:
✔ 信件不會被擋,只會被加上 spam header
✔ Dovecot 會依據 IMAPSieve 進行後續分類
等你之後測試穩定,可調整為:
- D_REJECT、或
- D_DISCARD
8. MySQL bayes_vars schema 修正
SpamAssassin 4.0 相較舊版多了:
oldest_token_agenewest_token_age必須 NOT NULL
你的 entrypoint.sh 會自動修正:
ALTER TABLE bayes_vars ADD COLUMN oldest_token_age INT(11) ...
ALTER TABLE bayes_vars MODIFY COLUMN newest_token_age INT(11) NOT NULL DEFAULT 0;
✔ 自動修正確保不會出現 SA 4.0 “oldest_token_age missing” 錯誤
✔ 不需要手工修改
9. 整體 SA + Dovecot + Amavis 流程圖
Inbound mail:
Internet → Postfix → Amavis → SpamAssassin → Postfix → Dovecot → 用戶信箱
Outbound mail:
用戶 → Dovecot (SASL) → Postfix (submission) → Amavis (DKIM + scan) → Internet
Learn SPAM/HAM:
使用者移動郵件 → Dovecot IMAPSieve → sa-remote-learn → SpamAssassin → MySQL (Bayes/TxRep)
10. 最後建議與最佳化方向
✔ 1. Bayes 必須定期 expire
可新增 crontab 執行:
sa-learn --sync
✔ 2. 至少每月 backup Bayes SQL
備份 table:
bayes_token
bayes_vars
bayes_seen
txrep
✔ 3. 評估開啟 Pyzor / Razor / DNSBL
SpamAssassin 效果可進一步提升 20–40%。
✔ 4. Roundcube 加裝 MarkAsJunk2 plugin
UX 更好,可直接按鈕 learn spam/ham。
結語
本篇完整介紹 SpamAssassin 4.0 在你架構中的角色:
- SQL Bayes + TxRep(永久化學習)
- 透過 IMAPSieve 自動學習 SPAM/HAM
- sa-update + sa-compile 自動規則更新
- Docker 化部署與 MySQL schema 自動修補
- 與 Amavis、Dovecot 的整合
這套架構已經達到「企業等級郵件防護」的水準,並且充分容器化、模組化,可隨時擴展。