Skip to content

Nuface Blog

隨意隨手記 Casual Notes

Menu
  • Home
  • About
  • Services
  • Blog
  • Contact
  • Privacy Policy
  • Login
Menu

SpamAssassin 4.0:SQL Bayes、TxRep、sa-update、自動學習與 Docker 化完整部署指南

Posted on 2025-11-202025-11-21 by Rico

【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_token
  • bayes_vars
  • bayes_seen

✔ MySQL 儲存 TxRep(白名單/黑名單評分)

  • txrep table

好處:

✔ 學習永久化
✔ 容器重建不受影響
✔ 讓 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_age
  • newest_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 的整合

這套架構已經達到「企業等級郵件防護」的水準,並且充分容器化、模組化,可隨時擴展。

Recent Posts

  • Postfix + Let’s Encrypt + BIND9 + DANE Fully Automated TLSA Update Guide
  • Postfix + Let’s Encrypt + BIND9 + DANE TLSA 指紋自動更新完整教學
  • Deploying DANE in Postfix
  • 如何在 Postfix 中部署 DANE
  • DANE: DNSSEC-Based TLS Protection

Recent Comments

  1. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on High Availability Architecture, Failover, GeoDNS, Monitoring, and Email Abuse Automation (SOAR)
  2. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on MariaDB + PostfixAdmin: The Core of Virtual Domain & Mailbox Management
  3. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Daily Operations, Monitoring, and Performance Tuning for an Enterprise Mail System
  4. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Final Chapter: Complete Troubleshooting Guide & Frequently Asked Questions (FAQ)
  5. Building a Complete Enterprise-Grade Mail System (Overview) - Nuface Blog on Network Architecture, DNS Configuration, TLS Design, and Postfix/Dovecot SNI Explained

Archives

  • December 2025
  • November 2025
  • October 2025

Categories

  • AI
  • Apache
  • Cybersecurity
  • Database
  • DNS
  • Docker
  • Fail2Ban
  • FileSystem
  • Firewall
  • Linux
  • LLM
  • Mail
  • N8N
  • OpenLdap
  • OPNsense
  • PHP
  • QoS
  • Samba
  • Switch
  • Virtualization
  • VPN
  • WordPress
© 2025 Nuface Blog | Powered by Superbs Personal Blog theme