一份 VPN 日志里的三个时钟:客户端、网关、采集器
客户端日志、网关记录和采集器到达是三个各有其时钟的事件。在比较时间戳之前,先确认字段的来源。
VPN 事件的时间线通常始于两个相差几分钟的时间戳,以及一个显示着不同小时数的界面。诱惑在于挑一个当正确,把另一个改写掉。两者都可能正确,因为它们由不同的时钟记录的是不同的事件。所谓 VPN 只有一个时钟,这是神话;真正的工作是弄清哪个组件写了哪个字段。
神话:VPN 只有一个时钟
客户端在尝试连接时写下一个事件。网关在收到或接受这次尝试时写下一个事件。采集器在收到网关消息时写下到达时间。这是三个事件,每一个都由写入组件所信任的那个时钟打上时间戳。把它们压成一条时间线是一种便利,恰好掩盖了你想解释的那处不一致。
数字通常相差几秒到几分钟,这很正常。关键在于这处差异是投递延迟、时钟偏移,还是真正不同的事件。要判断你看到的是哪一种,需要每个字段的来源,而不是对哪台机器更对的更强意见。
先读来源,再读数值
在比较数值之前,先确认每个值是谁产生的、属于哪个字段。syslog 消息携带来自来源的时间戳,正如 RFC 5424 所描述,该格式还可以携带描述同步与精度的时质信息。同一格式也允许来源在无法读取系统时间时完全不发送时间戳,这本身就是一个有用的信号。
journalctl -o short-iso --utc -n 20
logger -t vpn-check "test event"
客户端也可以把时间值作为应用元数据发送,保存它的服务应当标注为客户端自报,而不是当作独立核实过的值。这个标注就是证据与主张之间的差别。为某个案子导出日志时,要把字段名、来源和偏移放在一起。把它们简化成一个顺眼的本地时间,恰恰毁掉了你需要的信息。
如果你说不清某个字段是哪个组件写的,就停下来。拿它去和别的东西比较,只是猜测。
时区显示不是另一个时刻
同一时刻显示为 10:00Z 和 18:00+08:00 并不是矛盾,把它当矛盾处理会浪费半天。比较之前先把两者都换算成 UTC,并把原文与换算结果并排放着。一边是小数、另一边是整秒,同样不是冲突。精度不等于准确:带毫秒的值仍可能来自一个偏了几分钟的时钟。
date -u +%FT%TZ
timedatectl
投递延迟是另一种常见的解释。网关记录它何时接受连接,采集器记录消息何时到达它那里,所以两者之间的空档是传输时间。这个空档说明的是日志管道,而不是 VPN 会话。把它标注为到达时间,它就不再与事件时间争夺位置。
关联而不改写证据
保留原始时间戳,如果需要一个共同视图,就另加一列派生值。在备注里解释换算,而不是去改源记录,因为源记录才是后来复核者要查的东西。采集器的到达时间只要存在,就单独保留。
chronyc tracking
journalctl --utc -u openvpn-client@work -n 50 --no-pager
更改设备时钟不是隐私控制,也不会改写另一个系统已经持有的记录。它还会让支持证据更难比较,并可能破坏依赖时间的证书与代码校验。日常运行要让时钟保持同步,任何刻意的偏移都应当当作要排查的故障。如果两条记录看起来顺序不对,先看时钟同步和投递,再考虑重建一段新历史。
应当放弃的神话是:VPN 只有一个时间。问清每个字段是什么写的、写的时候发生了什么,时间线就会变成一组带标签的观察,而不是一处矛盾。