Apache SpamAssassin 常用 CLI 命令与工具详解
详解 Apache SpamAssassin 3.4.6 自带 8 个命令行工具:spamassassin 单封过滤与去标记、spamc 客户端评分与健康探测、spamd 守护进程监听与访问控制、sa-learn 贝叶斯训练备份、sa-update 规则更新、sa-compile 编译加速与两个辅助工具,每条命令附语法与实测回显。
Apache SpamAssassin 常用 CLI 命令与工具详解
目标:详解 Apache SpamAssassin 3.4.6 自带的 8 个命令行工具——spamassassin、spamc、spamd、sa-learn、sa-update、sa-compile、sa-awl、sa-check_spamd,覆盖每个工具的功能、语法、常用参数与真实回显,全部命令在 Ubuntu 22.04.5 服务器实测验证。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- 主机名:mail01.example.com
- Apache SpamAssassin:3.4.6-1ubuntu0.22.04.1(
spamassassin、spamc软件包) - Perl:5.34.0
- 实例内全部命令行工具(实测清单):
ls /usr/bin /usr/sbin | grep -E "^(spam|sa-)" | sort -u
真实回显:
sa-awl
sa-check_spamd
sa-compile
sa-learn
sa-update
spamassassin
spamc
spamd
- 主要工具路径(实测):
/usr/bin/spamassassin、/usr/bin/spamc、/usr/sbin/spamd、/usr/bin/sa-learn、/usr/bin/sa-update - 服务名:
spamassassin.service(spamd 守护进程,默认监听 127.0.0.1:783) - 测试邮件目录:
/var/mailtest/
二、工具概览
| 工具 | 路径 | 用途 |
|---|---|---|
spamassassin | /usr/bin/spamassassin | 单封邮件命令行过滤前端,直接载入全套规则打分、改写或去标记 |
spamc | /usr/bin/spamc | 轻量客户端,把邮件经 TCP 发给 spamd 评分,适合高频调用 |
spamd | /usr/sbin/spamd | 常驻守护进程,监听 783 端口,批量处理 spamc 请求 |
sa-learn | /usr/bin/sa-learn | 贝叶斯语料训练与数据库管理(dump/forget/sync/backup) |
sa-update | /usr/bin/sa-update | 在线更新官方规则集 |
sa-compile | /usr/bin/sa-compile | 把规则正则编译为本地加速模块 |
sa-awl | /usr/bin/sa-awl | 查看自动白名单数据库 |
sa-check_spamd | /usr/bin/sa-check_spamd | 对 spamd 发起 ping 健康检查 |
💡
spamassassin每次调用都要完整加载 Perl 规则(秒级);高频场景一律走spamc → spamd链路(毫秒级,实测 GTUBE 判定 0.7 秒内含连接开销)。
三、前置条件
- SpamAssassin 3.4.6 已安装,
spamassassin --version输出SpamAssassin version 3.4.6。 - spamd 已由 systemd 启动:
systemctl is-active spamassassin返回active。 - 已安装
net-tools(含netstat)与perl-doc。 - 准备两封测试邮件(GTUBE 标准垃圾样例与正常邮件,正文标准串为官方 GTUBE 常量):
mkdir -p /var/mailtest
cat > /var/mailtest/gtube.eml <<'EOF'
From: Sender <sender@example.net>
To: Recipient <recipient@example.com>
Subject: Test spam mail (GTUBE)
Date: Thu, 09 Oct 2026 08:00:00 +0800
Message-ID: <GTUBE1@example.net>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
This is the GTUBE, the
Generic
Test for
Unsolicited
Bulk
Email
If your spam filter supports it, the GTUBE provides a test by which you
can verify that the filter is installed correctly and is detecting incoming
spam. You can send yourself a test mail containing the following string of
characters (in upper case and with no white spaces and line breaks):
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
You should send this test mail from an account outside of your network.
EOF
cat > /var/mailtest/ham.eml <<'EOF'
From: Alice Zhang <alice@example.com>
To: Bob Li <bob@example.com>
Subject: Weekly project meeting minutes
Date: Fri, 10 Oct 2026 10:20:00 +0800
Message-ID: <20261010102000@example.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Hi Bob,
Here are the minutes from this week project meeting:
1. The new feature branch was merged into main.
2. QA finished the regression pass, no blockers found.
3. Next milestone demo is scheduled for next Tuesday.
Please review and add anything I missed.
Best regards,
Alice
EOF
四、spamassassin:单封邮件过滤前端
4.1 功能与语法
spamassassin --help 回显(前段原样):
SpamAssassin version 3.4.6
running on Perl version 5.34.0
For more information read the spamassassin man page.
Usage:
spamassassin [options] [ < mailmessage | path ... ]
spamassassin -d [ < mailmessage | path ... ]
spamassassin -r [ < mailmessage | path ... ]
spamassassin -k [ < mailmessage | path ... ]
spamassassin -W|-R [ < mailmessage | path ... ]
Options:
-L, --local Local tests only (no online tests)
-r, --report Report message as spam
-k, --revoke Revoke message as spam
-d, --remove-markup Remove spam reports from a message
-C path, --configpath=path, --config-file=path
Path to standard configuration dir
-p prefs, --prefspath=file, --prefs-file=file
Set user preferences file
--siteconfigpath=path Path to site configs
(def: /etc/spamassassin)
--cf='config line' Additional line of configuration
-x, --nocreate-prefs Don't create user preferences file
以 root 首次运行时会自动创建用户偏好文件(真实回显):
Oct 12 00:44:23.612 [4647] warn: config: created user preferences file: /root/.spamassassin/user_prefs
4.2 -t:测试模式,输出改写后的完整邮件
spamassassin -t /var/mailtest/gtube.eml
真实回显(改写后邮件头部):
Received: from localhost by mail01.example.com
with SpamAssassin (version 3.4.6);
Mon, 12 Oct 2026 00:44:24 +0000
From: Sender <sender@example.net>
To: Recipient <recipient@example.com>
Subject: Test spam mail (GTUBE)
Date: Thu, 09 Oct 2026 08:00:00 +0800
Message-Id: <GTUBE1@example.net>
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mail01.example.com
X-Spam-Flag: YES
X-Spam-Level: **************************************************
X-Spam-Status: Yes, score=1000.0 required=5.0 tests=GTUBE,NO_RECEIVED,
NO_RELAYS autolearn=no autolearn_force=no version=3.4.6
输出末尾附评分明细表:
Content analysis details: (1000.0 points, 5.0 required)
pts rule name description
---- ---------------------- --------------------------------------------------
1000 GTUBE BODY: Generic Test for Unsolicited Bulk Email
-0.0 NO_RELAYS Informational: message was not relayed via SMTP
-0.0 NO_RECEIVED Informational: message has no Received headers
正常邮件实测:
spamassassin -t /var/mailtest/ham.eml
真实回显(关键头部):
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on mail01.example.com
X-Spam-Level:
X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RECEIVED,NO_RELAYS
autolearn=unavailable autolearn_force=no version=3.4.6
spamassassin -t gtube.eml; echo $?
真实回显(-t 测试模式恒返回 0):
EXIT=0
4.3 -e:以退出码输出判定结果(供脚本调用)
spamassassin -e < /var/mailtest/gtube.eml >/dev/null 2>&1; echo SPAM_EXIT=$?
spamassassin -e < /var/mailtest/ham.eml >/dev/null 2>&1; echo HAM_EXIT=$?
spamassassin -t -e < /var/mailtest/gtube.eml >/dev/null 2>&1; echo SA_E_EXIT=$?
真实回显(垃圾邮件退出码 5,正常邮件退出码 0,-t -e 组合同样返回 5):
SPAM_EXIT=5
HAM_EXIT=0
SA_E_EXIT=5
4.4 --cf:命令行内联参数覆盖
不修改配置文件,临时追加配置行验证行为:
spamassassin --cf="required_score 2000" -t gtube.eml | grep X-Spam-Status
spamassassin --cf="rewrite_header Subject [CUSTOM-MARK]" -t gtube.eml | grep "^Subject"
真实回显:
X-Spam-Status: No, score=1000.8 required=2000.0 tests=BAYES_50,GTUBE,
Subject: [CUSTOM-MARK] Test spam mail (GTUBE)
4.5 -d:去除 SpamAssassin 标记
先用 spamc 生成一封已改写邮件,再用 -d 还原:
spamc < /var/mailtest/gtube.eml > /tmp/marked.eml
spamassassin -d < /tmp/marked.eml | grep -E "^Subject|X-Spam-Flag"
真实回显(主题恢复原样、X-Spam-Flag 等标记头全部去除):
Subject: Test spam mail (GTUBE)
五、spamc:轻量客户端
5.1 功能与语法
spamc -h 回显(头部原样):
SpamAssassin Client version 3.4.6
compiled with SSL support (OpenSSL 3.0.2 15 Mar 2022)
Usage: spamc [options] [-e command [args]] < message
常用参数与真实默认值(摘自 -h 全文):
| 参数 | 默认值 | 说明 |
|---|---|---|
-d, --dest | localhost | spamd 服务端地址,可逗号分隔多个 |
-p, --port | 783 | spamd 端口 |
-t, --timeout | 600 | 与 spamd 通信超时(秒) |
-n, --connect-timeout | 600 | 建立连接超时(秒) |
--filter-retries | 1 | spamd 失败时过滤重试次数 |
--filter-retry-sleep | 1 | 过滤重试间隔(秒) |
--connect-retries | 3 | 连接 spamd 重试次数 |
--retry-sleep | 1 | 连接重试间隔(秒) |
-s, --max-size | 500k | 送检邮件大小上限(字节) |
-u, --username | 当前用户 | 交给 spamd 处理时使用的用户名 |
-S, --ssl | 关 | 以 SSL 连接 spamd |
-U, --socket | — | 走 UNIX 域套接字连接 |
-x, --no-safe-fallback | 关 | 关闭「spamd 不可用时原样放行」的安全回退 |
5.2 -c:仅输出评分摘要行并设置退出码
spamc -c < /var/mailtest/gtube.eml; echo $?
spamc -c < /var/mailtest/ham.eml; echo $?
真实回显(垃圾邮件退出码 1,正常邮件退出码 0):
1000.0/5.0
1
0.0/5.0
0
5.3 -y:仅列出命中的规则名
spamc -y < /var/mailtest/gtube.eml
spamc -y < /var/mailtest/ham.eml
真实回显:
GTUBE,NO_RECEIVED,NO_RELAYS
NO_RECEIVED,NO_RELAYS
5.4 -R:输出完整评分报告
spamc -R < /var/mailtest/gtube.eml
真实回显(报告首段与明细表):
1000.0/5.0
Spam detection software, running on the system "mail01.example.com",
has identified this incoming email as possible spam. The original
message has been attached to this so you can view it or label
similar future email. If you have any questions, see
@@CONTACT_ADDRESS@@ for details.
Content analysis details: (1000.0 points, 5.0 required)
pts rule name description
---- ---------------------- --------------------------------------------------
-0.0 NO_RELAYS Informational: message was not relayed via SMTP
1000 GTUBE BODY: Generic Test for Unsolicited Bulk Email
-0.0 NO_RECEIVED Informational: message has no Received headers
5.5 -E:正常过滤并按判定设置退出码
spamc -E < /var/mailtest/gtube.eml >/dev/null; echo $?
spamc -E < /var/mailtest/ham.eml >/dev/null; echo $?
真实回显:
1
0
5.6 -K:spamd 存活探测
echo -n "" | spamc -K
真实回显(SPAMD/1.5 0 表示服务存活,退出码 0):
SPAMD/1.5 0
5.7 -d:跨主机调用远端 spamd
在另一台装有 spamc 的服务器上,指定服务端地址与端口:
spamc -d mail01.example.com -p 783 -c < /var/mailtest/gtube.eml; echo CROSS_EXIT=$?
真实回显(服务端已放行来源网段时;访问控制配置见第六章):
1000.0/5.0
CROSS_EXIT=1
六、spamd:守护进程与访问控制参数
6.1 功能与语法
spamd --help 回显(关键段原样):
SpamAssassin Server version 3.4.6
running on Perl 5.34.0
with SSL support (IO::Socket::SSL 2.074)
with zlib support (Compress::Zlib 2.102)
For more details, use "man spamd".
Usage:
spamd [options]
--listen 的官方语法说明(help 原文):
The --listen option (or -i) may be specified multiple times, its syntax
is: [ ssl: ] [ host-name-or-IP-address ] [ : port ] or an absolute path
(filename) of a Unix socket. If port is omitted it defaults to --port or
to 783. Option --ssl implies a prefix 'ssl:'. An IPv6 address should be
enclosed in square brackets, e.g. [::1]:783, an IPv4 address may be but
need not be enclosed in square brackets. An asterisk '*' in place of a
hostname implies an unspecified address, ('0.0.0.0' or '::'), i.e. it
binds to all interfaces. An empty option value implies '*'. A default is
'--listen localhost', which binds to a loopback interface only.
6.2 常用启动参数
| 参数 | 说明 |
|---|---|
-d, --daemonize | 转入后台运行(systemd 单元采用该方式) |
-i, --listen=[ip[:port]] | 监听地址与端口,默认 localhost 仅回环,可多次指定 |
-p, --port=port | 监听端口,默认 783,可被 -i 覆盖 |
-A, --allowed-ips=ip,... | 客户端 IP 白名单,不配则仅回环可连 |
-m, --max-children=num | 最大并发子进程数 |
--min-children / --min-spare / --max-spare / --max-conn-per-child | 子进程池与连接数调优 |
-c, --create-prefs | 为用户自动创建 user_prefs |
-x, --nouser-config | 禁用用户级配置文件 |
-u / -g | 降权运行的用户/组 |
-H [dir], --helper-home-dir | 辅助进程 HOME 目录 |
-L, --local | 只做本地测试(不做 DNS 在线检测) |
-r, --pidfile | 写 PID 文件 |
--socketpath=path | 监听 UNIX 域套接字(配合 --socketowner/--socketgroup/--socketmode) |
--ssl / --ssl-port | 启用 SSL 监听 |
-l, --allow-tell | 允许客户端提交学习/举报 |
-V, --version | 打印版本 |
6.3 systemd 托管与 /etc/default/spamassassin
服务单元 /lib/systemd/system/spamassassin.service(实测内容):
[Unit]
Description=Perl-based spam filter using text analysis
After=network.target
[Service]
Type=forking
PIDFile=/run/spamd.pid
EnvironmentFile=-/etc/default/spamassassin
ExecStart=/usr/sbin/spamd -d --pidfile=/run/spamd.pid $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
StandardOutput=null
StandardError=null
Restart=always
[Install]
WantedBy=multi-user.target
启动参数由 /etc/default/spamassassin 提供(默认有效行):
OPTIONS="--create-prefs --max-children 5 --helper-home-dir"
PIDFILE="/var/run/spamd.pid"
CRON=0
运行状态与默认监听(实测):
systemctl status spamassassin --no-pager -l
netstat -lntp | grep 783
真实回显:
● spamassassin.service - Perl-based spam filter using text analysis
Loaded: loaded (/lib/systemd/system/spamassassin.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-10-12 00:45:53 UTC; 3s ago
Main PID: 4811 (spamd)
Tasks: 3 (limit: 5753)
Memory: 97.1M
CGroup: /system.slice/spamassassin.service
├─4811 /usr/bin/perl "-T -w" /usr/sbin/spamd -d --pidfile=/run/spamd.pid --create-prefs --max-children 5 --helper-home-dir
├─4813 "spamd child"
└─4814 "spamd child"
tcp 0 0 127.0.0.1:783 0.0.0.0:* LISTEN 5635/perl
spamd 处理请求的日志(journalctl 实测,含判定耗时与得分):
Oct 12 00:46:11 mail01.example.com spamd[4813]: spamd: connection from 127.0.0.1 [127.0.0.1]:42338 to port 783, fd 5
Oct 12 00:46:11 mail01.example.com spamd[4813]: spamd: processing message <GTUBE1@example.net> for root:65534
Oct 12 00:46:12 mail01.example.com spamd[4813]: spamd: identified spam (1000.0/5.0) for root:65534 in 0.7 seconds, 741 bytes.
Oct 12 00:46:12 mail01.example.com spamd[4813]: spamd: result: Y 999 - GTUBE,NO_RECEIVED,NO_RELAYS scantime=0.7,size=741,user=root,uid=65534,required_score=5.0,rhost=127.0.0.1,raddr=127.0.0.1,rport=42338,mid=<GTUBE1@example.net>,autolearn=no autolearn_force=no
6.4 实测:对外监听与访问白名单
需要跨机器调用时,修改 /etc/default/spamassassin 的 OPTIONS 增加 --listen 与 --allowed-ips 后重启:
cp /etc/default/spamassassin /etc/default/spamassassin.bak
sed -i "s|^OPTIONS=.*|OPTIONS=\"--create-prefs --max-children 5 --helper-home-dir --listen=0.0.0.0 --allowed-ips=127.0.0.0/8,192.168.1.0/24\"|" /etc/default/spamassassin
grep ^OPTIONS /etc/default/spamassassin
systemctl restart spamassassin && sleep 4 && netstat -lntp | grep 783
真实回显:
OPTIONS="--create-prefs --max-children 5 --helper-home-dir --listen=0.0.0.0 --allowed-ips=127.0.0.0/8,192.168.1.0/24"
tcp 0 0 0.0.0.0:783 0.0.0.0:* LISTEN 10904/perl
journalctl -u spamassassin --no-pager -n 30 | grep "server started"
真实回显:
Oct 12 01:48:20 mail01.example.com spamd[10904]: spamd: server started on IO::Socket::IP [0.0.0.0]:783 (running version 3.4.6)
本机判定与健康检查不受影响(实测):
spamc -c < /var/mailtest/gtube.eml; echo C_EXIT=$?
sa-check_spamd -H 127.0.0.1 -v
真实回显:
1000.0/5.0
C_EXIT=1
loaded Mail::SpamAssassin::Timeout
connecting to spamd for ping
SPAMD OK: 0.002 second ping response time
验证后恢复默认配置并确认回到回环监听:
mv /etc/default/spamassassin.bak /etc/default/spamassassin
systemctl restart spamassassin && sleep 4 && netstat -lntp | grep 783
systemctl is-active spamassassin
真实回显:
tcp 0 0 127.0.0.1:783 0.0.0.0:* LISTEN 10934/perl
active
⚠️ 白名单必须包含
127.0.0.0/8:本机 spamc、健康检查脚本都从回环发起连接,漏掉会导致全部被拒(真实报错见第九章 Q2)。
七、sa-learn:贝叶斯学习与数据库管理
7.1 功能与语法
sa-learn --help 回显(前段原样):
For more information read the manual page
Usage:
sa-learn [options] [file]...
sa-learn [options] --dump [ all | data | magic ]
Options:
--ham Learn messages as ham (non-spam)
--spam Learn messages as spam
--forget Forget a message
--use-ignores Use bayes_ignore_from and bayes_ignore_to
--sync Synchronize the database and the journal if needed
--force-expire Force a database sync and expiry run
--dbpath <path> Allows commandline override (in bayes_path form)
for where to read the Bayes DB from
--dump [all|data|magic] Display the contents of the Bayes database
Takes optional argument for what to display
--regexp <re> For dump only, specifies which tokens to
dump based on a regular expression.
-f file, --folders=file Read list of files/directories from file
--dir Ignored; historical compatibility
--file Ignored; historical compatibility
--mbox Input sources are in mbox format
--mbx Input sources are in mbx format
--max-size <b> Skip messages larger than b bytes;
defaults to 256 KB, 0 implies no limit
--showdots Show progress using dots
--progress Show progress using progress bar
--no-sync Skip synchronizing the database and journal
7.2 训练垃圾/正常语料
sa-learn --spam /var/mailtest/spam-corpus --progress
sa-learn --ham /var/mailtest/ham-corpus --progress
真实回显(各 5 封小语料):
100% Completed 344.85 msgs/sec in 00m00s
Learned tokens from 5 message(s) (5 message(s) examined)
100% Completed 524.05 msgs/sec in 00m00s
Learned tokens from 5 message(s) (5 message(s) examined)
7.3 --dump magic:查看贝叶斯统计
sa-learn --dump magic | grep -E "nspam|nham|ntokens|db version"
真实回显(上面 5+5 训练后):
0.000 0 3 0 non-token data: bayes db version
0.000 0 5 0 non-token data: nspam
0.000 0 5 0 non-token data: nham
0.000 0 116 0 non-token data: ntokens
7.4 相同邮件自动去重
对 250 封正文完全相同的垃圾邮件训练(实测):
sa-learn --spam /var/mailtest/bayes-spam
sa-learn --ham /var/mailtest/bayes-ham
sa-learn --spam /var/mailtest/bayes-spam2
sa-learn --dump magic | grep -E "nspam|nham|ntokens"
真实回显(250 封相同正文只入库 1 封,其余按去重跳过;正文唯一的 210 封全部入库):
Learned tokens from 1 message(s) (250 message(s) examined)
Learned tokens from 250 message(s) (250 message(s) examined)
Learned tokens from 210 message(s) (210 message(s) examined)
0.000 0 216 0 non-token data: nspam
0.000 0 255 0 non-token data: nham
0.000 0 1904 0 non-token data: ntokens
7.5 --forget 与 --sync
sa-learn --forget /var/mailtest/bayes-spam2/s1.eml
sa-learn --sync
真实回显(--sync 无输出即成功):
Forgot tokens from 1 message(s) (1 message(s) examined)
7.6 --backup:备份数据库
sa-learn --backup > /root/bayes-backup.txt
wc -l /root/bayes-backup.txt
head -3 /root/bayes-backup.txt
sa-learn --dump magic | grep -E "nspam|nham"
真实回显:
2374 /root/bayes-backup.txt
v 3 db_version # this must be the first line!!!
v 215 num_spam
v 255 num_nonspam
0.000 0 215 0 non-token data: nspam
0.000 0 255 0 non-token data: nham
7.7 样本量达标后 BAYES 规则参与评分
nspam/nham 超过 200+200 后重启 spamd,GTUBE 样例之外的业务邮件判定中开始出现 BAYES 规则(实测):
systemctl restart spamassassin
spamc -t < /var/mailtest/bayes-test.eml | grep -E "BAYES|X-Spam-Status"
真实回显:
X-Spam-Status: Yes, score=6.6 required=5.0 tests=BAYES_99,BAYES_999,
spamassassin -t /var/mailtest/bayes-test.eml | grep -E "pts rule|BAYES_9"
真实回显:
0.2 BAYES_999 BODY: Bayes spam probability is 99.9 to 100%
3.5 BAYES_99 BODY: Bayes spam probability is 99 to 100%
八、sa-update:规则集更新
8.1 功能与语法
sa-update --help 回显(原样):
For more information read the sa-update man page.
Usage:
sa-update [options]
Options:
--channel channel Retrieve updates from this channel
Use multiple times for multiple channels
--channelfile file Retrieve updates from the channels in the file
--checkonly Check for update availability, do not install
--install filename Install updates directly from this file. Signature
verification will use "file.asc", "file.sha256",
and "file.sha512".
--allowplugins Allow updates to load plugin code (DANGEROUS)
--gpgkey key Trust the key id to sign releases
Use multiple times for multiple keys
--gpgkeyfile file Trust the key ids in the file to sign releases
--gpghomedir path Store the GPG keyring in this directory
--gpg and --nogpg Use (or do not use) GPG to verify updates
(--gpg is assumed by use of the above
--gpgkey and --gpgkeyfile options)
--import file Import GPG key(s) from file into sa-update's
keyring. Use multiple times for multiple files
--updatedir path Directory to place updates, defaults to the
SpamAssassin site rules directory
(default: /var/lib/spamassassin/3.004006)
--refreshmirrors Force the MIRRORED.BY file to be updated
--httputil util Force used download tool. By default first found
from these is used: curl, wget, fetch, lwp
-D, --debug [area=n,...] Print debugging messages
-v, --verbose Be verbose, like print updated channel names;
For more verbosity specify multiple times
-V, --version Print version
-h, --help Print usage message
-4 Force using the inet protocol (IPv4), not inet6
-6 Force using the inet6 protocol (IPv6), not inet
8.2 执行更新并核对
sa-update
真实回显(静默成功,退出码 0):
EXIT=0
核对更新结果:
ls -la /var/lib/spamassassin/3.004006/
grep -E "^# UPDATE" /var/lib/spamassassin/3.004006/updates_spamassassin_org.cf
ls /var/lib/spamassassin/3.004006/updates_spamassassin_org/ | wc -l
真实回显:
total 16
drwxr-xr-x 3 root root 4096 Oct 12 00:48 .
drwxr-xr-x 5 debian-spamd debian-spamd 4096 Oct 12 00:47 ..
drwxr-xr-x 2 root root 4096 Oct 12 00:48 updates_spamassassin_org
-rw-r--r-- 1 root root 3163 Oct 12 00:48 updates_spamassassin_org.cf
# UPDATE version 1938768
72
更新后确认规则加载无告警:
spamassassin --lint
真实回显(退出码 0,无输出即干净):
LINT=0
8.3 --checkonly:仅检查不安装
sa-update --checkonly; echo $?
真实回显(已是最新版时退出码 1,无输出):
EXIT=1
8.4 --version 与定时更新建议
sa-update --version
真实回显:
sa-update version 3.4.6 / svn1881784
running on Perl version 5.34.0
💡
/etc/default/spamassassin中CRON=0表示软件包未启用自动更新;建议以 cron 每日执行sa-update,并在更新成功后systemctl reload spamassassin让规则热加载。
九、sa-compile 与两个辅助工具
9.1 sa-compile:规则编译加速
把规则中的正则表达式编译为本地加速模块,依赖 re2c:
apt-get install -y re2c
time sa-compile
真实回显(编译产物安装段与耗时):
Installing /var/lib/spamassassin/compiled/5.034/3.004006/auto/Mail/SpamAssassin/CompiledRegexps/body_0/body_0.so
Installing /var/lib/spamassassin/compiled/5.034/3.004006/Mail/SpamAssassin/CompiledRegexps/body_0.pm
cp /tmp/.spamassassin4889VaQtUetmp/bases_body_0.pl /var/lib/spamassassin/compiled/5.034/3.004006/bases_body_0.pl
real 0m18.014s
user 0m13.716s
sys 0m4.349s
9.2 sa-awl:查看自动白名单数据库
sa-awl
真实回显(本环境尚未产生自动白名单数据,auto-whitelist 数据库文件不存在):
Cannot open file /root/.spamassassin/auto-whitelist: No such file or directory
💡 该数据库由 auto-whitelist 插件在评分过程中创建,默认路径为运行用户 HOME 下的
.spamassassin/auto-whitelist;有数据后即可用 sa-awl 查看。
9.3 sa-check_spamd:spamd 健康检查
sa-check_spamd --help 回显(原样):
sa-check_spamd version
For more details, use "perldoc sa-check_spamd".
Usage:
sa-check_spamd [options]
Options:
-c secs, --critical=secs Critical ping response threshold
-h, -?, --help Print usage message
-H hostname, --hostname=hostname Hostname of spamd service to ping
-p port, --port=port Port of spamd service to ping
--socketpath=path Connect to given UNIX domain socket
-t secs, --timeout=secs Max time to wait for a ping response
-v, --verbose Verbose debug output
-V, --version Output version info
实测:
sa-check_spamd -H 127.0.0.1 -v
真实回显(SPAMD OK 表示健康,退出码 0):
loaded Mail::SpamAssassin::Timeout
connecting to spamd for ping
SPAMD OK: 0.002 second ping response time
十、注意事项
spamc只读标准输入,文件名会被当作无关参数忽略(真实踩坑见第九章 Q1)。- 任何
.cf/.pre配置改动先spamassassin --lint再重启,避免语法错误导致 spamd 拒绝加载。 spamd默认仅监听127.0.0.1:783;对外开放必须同时配置--listen与--allowed-ips,白名单务必包含127.0.0.0/8。sa-update更新规则后执行systemctl reload spamassassin;sa-compile依赖re2c,编译产物随规则更新需重新生成。- 常用退出码语义速查:
| 命令 | 垃圾邮件 | 正常邮件 | 其他 |
|---|---|---|---|
spamassassin -e | 5 | 0 | — |
spamc -c / spamc -E | 1 | 0 | — |
spamc -K | 存活返回 0 | — | 服务异常非 0 |
sa-update | 已安装新规则 0 | 无更新 1 | 失败 4 及以上 |
spamassassin --lint | — | — | 0 干净 / 1 有问题 |
十一、常见问题
Q1:spamc -c 文件名 返回 0/0 且没有报错?
spamc 不接受文件名参数,只读标准输入;参数被忽略后以空输入触发「安全回退」,输出 0/0 且退出码 0。正确写法是重定向:spamc -c < /var/mailtest/gtube.eml,得 1000.0/5.0、退出码 1(见 5.2 节实测)。
Q2:日志刷 spamd: unauthorized connection from 127.0.0.1,本机 spamc 全部返回 0/0?
--allowed-ips 白名单没包含回环网段,本机发起的连接(含健康检查)全部被拒。真实日志:
Oct 12 00:53:05.935 [8] warn: spamd: unauthorized connection from 127.0.0.1 [127.0.0.1]:57020 to port 783, fd 5 at /usr/sbin/spamd line 1627.
处理:在 OPTIONS 中把 127.0.0.0/8 加入 --allowed-ips(见 6.4 节实测),重启后恢复。
Q3:spamd 启动日志出现 Can't locate Mail/SpamAssassin/CompiledRegexps/body_0.pm?
编译规则缺失,spamd 尝试加载失败(不影响基本判定)。真实日志:
Oct 12 00:45:52 mail01.example.com spamd[4811]: Can't locate Mail/SpamAssassin/CompiledRegexps/body_0.pm in @INC (you may need to install the Mail::SpamAssassin::CompiledRegexps::body_0 module) (@INC contains: /var/lib/spamassassin/compiled/5.034/3.004006 ...) at (eval 1897) line 1.
处理:apt-get install -y re2c && sa-compile 后重启 spamd,告警消失(实测约 18 秒编译完成,见 9.1 节)。
Q4:sa-update --checkonly 退出码 1 是不是失败了?
不是。--checkonly 在「无新版本可更新」时返回 1(见 8.3 节实测),返回 0 表示有可用更新;只有 4 及以上的退出码才代表执行失败。
Q5:健康检查(监控探针)能不能用 spamc -c < 某文件?
不能。spamc -c 会把送入内容当邮件打分,例如实测 spamc -c < /etc/hostname 返回 7.9/5.0、退出码 1,探针会一直误报。存活探测必须用专用报文:echo -n "" | spamc -K 或 sa-check_spamd,正常返回 SPAMD/1.5 0 与 SPAMD OK(见 5.6、9.3 节实测)。
十二、参考链接
- Apache SpamAssassin 官方站点:https://spamassassin.apache.org/
- 官方文档全集:https://spamassassin.apache.org/doc.html
- GTUBE 标准测试串说明:https://spamassassin.apache.org/gtube/
- 同机离线手册:
man spamassassin、man spamc、man spamd、perldoc Mail::SpamAssassin::Conf