引言

在构建跨平台邮件客户端的安全子系统时,单一检测模块的输出往往只有"是/否"的二元判断。但现实中邮件安全是一个连续的光谱——一封邮件可能 SPAM 评分良好但 URL 可疑,也可能附件安全但发件人域名信誉不佳。如何聚合这些异构信号,输出一个统一、可解释的安全评分,是构建可信邮件客户端的核心挑战。

本文介绍的 Composite Scorer(综合安全评分引擎)正是解决这一问题。它作为邮件安全子系统的"终审法官",接收来自垃圾邮件过滤器、钓鱼检测器、URL 分析器、域名信誉引擎、附件扫描器、邮件头伪造检测和身份验证引擎的 7 维信号,通过可配置加权算法输出 0-100 的综合评分和 5 级安全裁决。

架构设计

Composite Scorer 的设计哲学是:不直接做检测,只负责聚合裁决。这种单一职责让它成为安全子系统的最终一道关口。

核心数据结构包括:

  • SecuritySignal:单个安全信号,包含来源、评分、风险标签、详细描述和是否否决
  • SecurityVerdict:5 级安全裁决枚举(Trustworthy / LowRisk / ModerateRisk / HighRisk / Critical)
  • ScorerConfig:评分配置,含权重映射、否决阈值和缓存 TTL
  • ScoreReport:评分报告,含综合评分、裁决、信号贡献分解和置信度

涉及的 7 个信号来源:

信号来源默认权重说明
SpamFilter20垃圾邮件过滤评分
PhishingDetector20钓鱼检测评分
UrlAnalyzer15URL 信誉分析评分
DomainReputation15域名信誉评分
AttachmentScanner10附件安全扫描评分
HeaderForgery10邮件头伪造检测评分
AuthVerification10身份验证(DKIM/SPF/DMARC)评分

否决机制 (Veto)

否决是 Composite Scorer 最独特的特性。当单个信号评分低于 veto_threshold(默认 10)时,无论其他信号多好,最终评分都会被压制到阈值以下,直接判定为 Critical/HighRisk。这确保了"一票否决"——一个致命缺陷足以让整封邮件被标记为高危。

否决逻辑在内建的 ScoreInputBuilder 中也有体现:附件评分低于 20 或邮件头评分低于 20 时,信号会自动标记为 is_veto = true,实现"近否决"效果。

4 种预设策略

Composite Scorer 提供 4 种开箱即用的预设配置:

  • Paranoid(偏执模式):veto_threshold=20, cache_ttl=60s。宁可错杀,不可放过。适合高安全需求场景。
  • Balanced(平衡模式,默认):veto_threshold=10, cache_ttl=300s。所有 7 维信号等权重参与。
  • Relaxed(宽松模式):veto_threshold=5, cache_ttl=600s。减少误报,适合日常使用。
  • Minimal(最小模式):仅 4 个关键信号(Spam Phishing Attachment Auth),每种权重更高(30/30/20/20)。

Mini‌mal 模式的信号权重和恰好为 100,确保加权计算无需归一化。

置信度评分

评分的可信度取决于参与评分的信号数量:

  • 1 个信号 → 置信度 30%
  • 2 个信号 → 置信度 60%
  • 4 个信号 → 置信度 80%
  • 6 个信号 → 置信度 95%

置信度让调用方可以判断评分的可靠性——仅有 SPAM 评分的邮件,即使分数高,置信度也只有 30%。

ScoreInputBuilder 流式 API

为了方便从各个子模块收集评分并一次性裁决,Composite Scorer 提供了 ScoreInputBuilder 流式构建器:

let report = ScoreInputBuilder::new()
    .spam_score(90, "Bayesian filter: clean")
    .phishing_score(85, "No suspicious patterns")
    .url_score(100, "All URLs whitelisted")
    .domain_score(88, "Known sender domain")
    .attachment_score(100, "No attachments")
    .header_score(95, "Headers consistent")
    .auth_score(92, "DKIM SPF DMARC all pass")
    .score_with_preset("balanced")
    .unwrap();

assert!(report.is_safe());
assert!(!report.needs_quarantine());

每个 score_* 方法内部自动根据分数范围生成风险标签,附件和邮件头方法还包含自动否决逻辑。

缓存与性能

CompositeScorer 内置 TTL 缓存,避免对同一封邮件重复评分:

  • 默认 TTL 300 秒(平衡模式)
  • score_cached(key, signals) 自动检查缓存
  • score_batch(items) 批量评分(每条独立缓存)
  • evict_expired() 清理过期条目
  • 配置变更时自动清空缓存

C FFI 绑定

Composite Scorer 提供完整的 C ABI 绑定(composite_scorer_ffi.rs),共 18 个导出函数,覆盖:

  • 评分器生命周期:创建(4 种预设 自定义)/ 销毁
  • 核心评分:评分 / 批量评分
  • 缓存管理:大小查询 / 清理 / 驱逐
  • 配置管理:更新配置 / 获取预设名称
  • 输出:统计 JSON / 报告 JSON
  • 便捷:ScoreInputBuilder 的 C 端封装

这使得 WinUI (C /WinRT)、Android (JNI)、iOS (Obj-C/Swift) 和 Linux 客户端均可通过 FFI 调用 Rust 的核心评分逻辑。

工程亮点

  • 零外部依赖:仅使用 std::collections::HashMap 和 serde 序列化,无锁争用
  • 序列化支持:ScoreReport 和 SecurityVerdict 均实现 serde::Serialize,可直接序列化为 JSON 用于网络传输或数据持久化
  • 测试覆盖:38 个单元测试,覆盖完美信号、全否决信号、边界值、置信度阶梯、缓存驱逐、预设差异等场景
  • Builder 模式:ScoreInputBuilder 的链式调用让多信号聚合代码简洁可读

与子模块的协作关系

Composite Scorer 是安全子系统的最后一道关卡,它消费以下模块的输出:

  • SpamFilter → 输出 0-100 安全评分
  • PhishingDetector → 输出 0-100 钓鱼概率反向评分
  • UrlAnalyzer → 综合 URL 信誉评分
  • DomainReputation → 综合域名信誉评分
  • AttachmentScanner → 附件安全评分(<20 自动否决)
  • HeaderForgery → 邮件头伪造检测评分(<20 自动否决)
  • AuthVerification → DKIM/SPF/DMARC 身份验证评分

信号流经:子模块检测 → 评分归一化 → 加权聚合 → 否决检查 → 裁决分级 → 报告生成,形成完整的安全分析链路。

总结

Composite Scorer 的设计展示了 Rust 在邮件安全领域的工程实践:通过枚举的类型安全表达裁决等级,Builder 模式实现优雅的信号收集,HashMap 实现灵活的可配置权重,以及零成本抽象缓存提升性能。1155 行代码 38 个测试 18 个 C FFI 导出,构成了邮件安全系统的"终审法官"。

该引擎已在 Phase 10.15 中完成,累计通过 1147 单元测试。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部