摘要

  • RFC 5260 证明的是某次执行对某个邮件头位置、日期部分、时区和比较器所得的结果,而不是该时间值本身真实。
  • 若日期会触发隔离、拒收或审批,证据必须分别保存原始头部、选择坐标、解析与归一化、脚本版本、执行时刻以及动作结果。

系统没有报错,证据坐标却已经移动

合规网关曾用第二个 Received: 判断邮件是否在截止时刻前进入本地系统。后来安全团队在入口增加了一层检查设备。脚本没有修改,所有测试仍正常返回;但原来的第二行变成第三行,索引二指向了另一段传输。

绿色状态只能说明规则成功执行。它不能说明规则仍在观察原先那件事。

RFC 5260 的价值正在于它把计算说得很清楚:从哪一类字段取值、取第几个、怎样解释时区、抽取哪个日期部分、使用哪个比较器。组织的责任,是不把这套计算越权解释成完整历史。

索引是语法位置,不是信任等级

没有 index 时,date 使用同名字段中找到的第一个。:index 2 选择第二个;加上 :last 后从尾部反向计数。对于允许多个字段名的相关测试,计数还取决于脚本里字段列表的顺序。

这些规则可以复现,却不自带“最可信”的含义。RFC 的示例明确以字段偏移保持稳定为前提。新增网关、删除中继、重排字段或改变字段名列表,都可能让同一个数字选择不同证据。

因此,审计日志不能只写“index 2 命中”。它必须保存当时完整有序的邮件头清单,以及真正被选择的那一行。

一个 false 压缩了四种不同现实

字段不存在、语法不合法、日历值不可能,以及合法日期没有满足条件,都会无条件返回 false。对语言执行而言,它们都走同一分支;对安全运营而言,它们完全不同。

缺少预期的本地 Received: 可能意味着路径变化;不可能的日期可能是恶意输入;普通的不匹配只是业务条件未满足。如果日志只剩布尔值,事故响应者无法知道自动化当时看到了什么。

:count 也只把“被选字段存在且含合法日期”记为一,否则为零。它不是整个头部链的计数,更不是真实性评分。

时区是执行政策,不是邮件事实

:originalzone 保留字段中写入的偏移;:zone 把时间投影到指定固定偏移;两者同时出现是错误。两者都省略时,服务器必须使用本地时区。

这意味着相同邮件字节和相同规则在不同服务器配置下可能得到不同的民用时间判断。保留 +0800 只保留一个声明的偏移,不能证明地点、司法辖区或夏令时历史。切换到另一时区也只是改变比较视角,并没有提高源时间的可信度。

currentdate 只在一次执行内保持一致

同一次脚本执行中的所有 currentdate 必须指向同一个时刻。这样可以避免脚本在午夜前后两次取时而自相矛盾。

但这个保证的边界很窄。它不是发送时间、首次入队、最终投递、阅读或人工批准时间。RFC 还指出,随当前时间变化的行为更难被静态分析。要重放决策,必须知道执行主机、当时的时区政策与被固定的时刻。

解析正确不等于来源可信

RFC 的安全章节指出,Date: 通常由发件人加入,途中任何位置都可能修改。最上方的 Received: 通常由本地邮件系统加入,外部发件人或中间方更难伪造。

这是证据强弱的差别,不是绝对认证。顶部 Received: 可以较强地说明本地接收,却不能证明此前整条路径、内容创建时间或过滤后的动作。解析器能够证明字符串符合日期格式,不能证明谁控制了时钟。

为日期决策保留收据

对有后果的日期自动化,应保存:邮件与原始头部哈希;有序头部清单;字段名和实际选中项;:index、:last 与字段列表顺序;原始时间文本;语法和日历合法性;原始偏移;指定或本地时区;归一化值和日期部分;比较器、匹配方式与键值;Sieve 能力、脚本身份和版本;执行主机与固定的 currentdate;false 的具体原因;被选择的动作、执行结果以及最终邮箱或转发观察。

这份收据不会让日期变真。它只是阻止一次局部计算在失去上下文后,被误记成已经证明的历史。

Sources