Rspamd 的 score 与 action 不是一回事:日志里的 [12.30/15.00] 该怎么读
现象
常见的两类误读:
- 把日志里的
[12.30/15.00]当成“离拒收还差 2.7 分”,拿来做监控和告警。 - 看到 score 100500 却没拒信,就以为配置坏了。
Rspamd 在 FAQ 里写得很明确:score 是内部量,外部服务不应依赖 score;MTA 侧只看 action。官方原话大意是:永远用 action,score 只用于定义通用阈值和调试;score、action 阈值、真实 action 三者没有任何保证一致。
阈值文件与默认值
发行版自带 conf/actions.conf,不要直接改,升级会被覆盖:
actions {
reject = 15; # 达到此分拒收
add_header = 6; # 达到此分加头(标记为垃圾)
greylist = 4; # 达到此分做灰名单(发出 soft reject action)
# unknown_weight = 1.0;
# grow_factor = 1.1;
# subject = "***SPAM*** %s"
}
文件末尾用 .include 合并 $LOCAL_CONFDIR/local.d/actions.conf(duplicate=merge,priority=1)与 override.d/actions.conf(priority=10,严格覆盖)。所以改配置写 local.d/actions.conf:local.d 是键级合并,override.d 是整段替换。
校验顺序:先 rspamadm configtest,再 systemctl reload rspamd(不是 restart)。
3.12.0 起 rspamadm configdump 增加 --non-default,只打印本地覆盖项,便于确认自己到底改了什么。
actions{} 键的真实含义
这是最容易误会的地方:段名叫 actions,实际是“score 阈值表”。
Rspamd 真正会返回的 action 是:
- discard(收下但丢弃,仅特殊场景)
- reject
- rewrite subject
- add header
- no action
- soft reject(1.9 起还有 quarantine)
actions{} 里没有 discard、没有 soft reject、没有 quarantine 的键;只有一个特殊的 greylist 键,它是给 greylisting 模块用的分数阈值。
也就是说:阈值决定“通用”行为,但模块可以绕过阈值直接指定 action。
forced action 列表与日志读法
能直接设定 action 的模块(官方列表):
- greylist:需要灰名单时设 soft reject
- ratelimit:触发限速时设 soft reject
- dmarc:配置后可按发件域策略直接设定 action(默认不启用)
- antivirus:规则里显式配置时可设 action
- multimap:map 里写了 action 时生效
- replies:配置后对回复邮件设 no action
- force_actions:专门用来强制 action 的模块
- spamtrap:可对 spamtrap 设 bypass
- metadata_exporter:配置为无法上报时设 soft reject
日志里体现为 forced: 字段,且 score 会被改写成阈值量级:
...(default: T (reject): [100500.00/15.00] [...])... forced: reject "test"; score=100500.00 (set by bla)
读法:先看 forced:,再看括号里的 (reject) 和 [score/threshold]。
soft reject 与 reject 的区别
soft reject = 让 MTA 返回临时错误(4xx),真实邮件服务器会重试,垃圾机器人通常不会。所以灰名单、限速用 soft reject,而不是 reject。reject 是最终拒收。
“用户说发信被延迟几分钟才到”和“被拒收”是两条完全不同的链路,排查入口不同:前者看 greylist/ratelimit 模块,后者看 reject 阈值与 RBL、SPF 等符号权重。
早停:同一封信两次扫描分数不同
一旦达到 reject 分数,Rspamd 会停止后续检查以节省资源,但在到达阈值之前已经发出的网络检查(DNS/RBL 等)仍会跑完并回填。于是同一封邮件可能得到不同分数,但都 ≥ reject 阈值。
要拿到完整结果:请求时带 HTTP 头 Pass: all,rspamc 客户端对应 -p 参数。
自定义 action 的写法与坑
actions {
# 只给阈值
my_action = { score = 9.0; },
# 只强制、不参与阈值
phishing = { flags = ["no_threshold"]; },
}
限制:一封邮件最终只应用一个 action,所以定义两个同阈值 action 没有意义。
相关全局属性:
grow_factor:后续符号的权重乘数,默认 1.0(不放大);score = score + grow_factor * weight,grow_factor = grow_factor * grow_factor;负分不影响该值。subject:rewrite subject 时替换主题的模板,%s原主题,%d分数。unknown_weight:给未在任何地方注册权重的符号兜底;不设则未注册符号被静默忽略;设了意味着所有规则都会被检查。
可执行的排查/调优顺序
- 确认改动生效:写
local.d/,rspamadm configtest,rspamadm configdump --non-default,reload。 - 单封定位:
rspamc扫一遍原信,看 action、forced:、参与符号与权重。 - 监控口径:统计 action 分布(no action / add header / soft reject / reject),而不是 score 均值或分位数。score 不可比。
- 阈值是钝器:动 add_header/reject 是全局平移,只适合整体标定偏了;单个发件人误判应该改符号权重、multimap 白名单或 bayes 训练。
举例:mailcow 文档给的是全局 reject=15、add_header=8、greylist=7;nixos-mailserver 文档给的是关闭拒收 actions { reject = null; add_header = 6; greylist = 4; }(reject 默认 15)。这些数值来自各自发行配置,说明“默认可改”,不能当统一推荐值。
项目信息
- 仓库:https://github.com/rspamd/rspamd
- 默认 actions 配置:https://github.com/rspamd/rspamd/blob/master/conf/actions.conf
- Metrics/action 文档:https://rspamd.com/doc/configuration/metrics.html
- FAQ(scores 与 actions):https://rspamd.com/doc/faq.html