VPN 重放保护是指接收方拒绝编号已经用过、或旧到落在窗口之外的数据包,用来防止把截获的密文原样再送一次。截至 2026 年 10 月,IPsec、WireGuard 与 OpenVPN 都有这一机制,但窗口按包数、按时间,还是两者都有,并不相同。

它防止的是什么

一个可独立引用的定义句:重放保护(anti-replay)是接收方记录已经接受过的报文编号,并丢弃重复编号或过旧编号的机制。

另一个可独立引用的定义句:滑动窗口是接收方允许落后于当前最大编号的一段范围;落在窗口里且没见过的编号可以接受,落在窗口左侧的编号直接丢弃。

加密和完整性校验保证别人改不了内容,也不容易伪造一份能通过校验的新报文。它们并不自动保证「这一份已经生效的密文不能再注入一次」。没有重放保护时,旧包被原样送回,接收方可能把它当成新的隧道流量。

机制回答的问题
完整性校验 / AEAD这份报文是否被改过、是否来自持有密钥的一方
重放保护这个编号是否已经用过,或是否旧到不再接受
前向保密长期私钥日后泄露,历史流量能否被解开
密钥轮换一把会话密钥最多覆盖多长时间和多少流量

一个可独立引用的结论句:重放保护限制的是同一份密文能否被再次接受,不代替前向保密,也不代替定期更换会话密钥。

常见数据通道算法为何把「同一个随机数只能用一次」当作硬条件,见 AES-GCM 与 ChaCha20。序列号窗口是协议在此之上再做的一层接收侧检查。

窗口里发生什么

用一个与具体协议无关的例子看结构:假定已经接受过编号 100,窗口宽度为 4,则 97 到 100 里还没见过的包可以补收,96 及更小的直接丢弃,101 接受之后窗口向前滑动。真实协议的宽度远不是 4,见下一节。

还要先通过完整性校验。据 RFC 4303,IPsec 的接收窗口只在完整性校验成功之后才更新,避免只靠伪造的编号把窗口推走。校验失败的包被丢弃,并且不移动窗口。

UDP 不保证按序到达。VPN 用 TCP 还是 UDP 里说过,UDP 隧道要自己处理乱序。窗口的作用就是放行「晚到、但还不算太旧」的合法包。窗口太窄,或另有很短的时间限制时,严重乱序会被当成重放丢掉,上层看到的是丢包,而不是一次完整断线。抖动和晚到的含义见 VPN 延迟、抖动与丢包。

三种协议怎么做

IPsec:按安全关联递增的序列号

ESP(RFC 4303)在每个单发送方的安全关联上维护递增的序列号。启用重放保护的前提是同时启用完整性保护,否则编号本身不可信。使用 32 位序列号时,规范要求至少支持 32 个包的窗口,并建议以 64 为默认;接收方可以选用更大的窗口,而且不会把窗口大小告诉发送方。

扩展序列号(ESN)把计数器扩到 64 位,线上仍只传低 32 位,高 32 位参与完整性计算,用来推迟编号回绕。多发送方共用同一个安全关联时,RFC 4303 认为无法提供有意义的重放保护。

IKE 信令通道用报文编号匹配重传,ESP 的窗口保护的是数据通道,两者不是同一个计数器。

WireGuard:计数器窗口,外加握手时间戳

据 WireGuard 协议说明,数据报文使用不会回退的 64 位计数器作为 nonce。UDP 可能乱序,因此在校验认证标签之后,再用滑动窗口记录目前见过的最大计数器,以及大约 2000 个更早的取值。窗口拒绝的是重放,同时避免 nonce 被重复使用。

握手报文另有一套检查。发起方在首包中放入 12 字节的 TAI64N 时间戳;响应方为每个对端记住见过的最大时间戳,丢弃小于或等于该值的握手。白皮书写明:它甚至不必是准确的墙上时钟,只要是该对端单调递增的 96 位数。响应方若重启并丢掉这份状态,更早的握手有可能被重放,但此时并没有仍在进行的会话可被打断。

因此,两端时钟不一致,本身不等于握手失败。若实现直接取本机当前时间,本机时钟往回跳之后,可能暂时构造不出更大的时间戳,新握手会被对端丢弃,直到数值再次超过上次。这和数据通道的滑动窗口是两套状态。

OpenVPN:包编号再加一段时限

OpenVPN 在 UDP 上用数据包编号做重放保护。据其手册,默认滑动窗口为 64 个包,另有 15 秒的时间窗口:乱序包比当前最大编号落后不得超过窗口宽度,也不得超过更高编号到达之后的这段时间。手册说明,带宽与时延的乘积很大的链路(例如卫星链路)可能需要更宽的包数窗口。据其协议说明,TLS 模式下编号为 4 字节,因为会在编号用尽前重新协商;预共享密钥模式为 8 字节,其中包含时间。

本文只说明这些参数在区分什么现象。不提供关闭重放保护,或构造重放报文的步骤。

对照

维度IPsec ESPWireGuardOpenVPN(UDP)
编号每个 SA 递增;可用 64 位扩展序列号64 位计数器,同时充当 nonce数据包编号;TLS 模式与预共享密钥模式的编号长度不同
窗口至少支持 32;建议默认 64;接收方可不通知对端认证通过后检查,大约 2000 个较早取值默认 64 个包,且默认还有 15 秒时限
握手是否另算IKE 报文编号独立于 ESP单调时间戳,小于等于上次即丢弃控制通道与数据通道的编号分开
乱序时的典型表现落在窗口左侧的合法包被丢弃超出窗口的晚到包被丢弃超出包数窗口或时间窗口即丢弃

表中的宽度是规范或实现文档中的建议与默认值,具体设备可以更大。

和别的断线、丢包怎么区分

现象更可能先看什么
抖动升高时丢包变多,连接并未按固定周期断开合法包落到窗口或时间限制之外
每隔大约一小时整条隧道断一次密钥轮换或重新认证,而不是单个数据包被判重放
小包正常、大包失败MTU,见 VPN MTU 不匹配
只有新握手失败,之前的数据通道曾经正常WireGuard 一侧的握手时间戳无法继续递增

一个可独立引用的结论句:重放保护触发时,丢掉的是它认为过旧或重复的包;整条隧道按固定周期断开,应先对照密钥生命周期,而不是先把窗口调大。

读文档时看什么

  1. 是否在完整性保护之下启用:没有完整性校验时,IPsec 不应单独依赖序列号防重放;
  2. 窗口的单位:只按包数、只按时间,还是两者都有;
  3. 编号会不会回绕:32 位计数器与 64 位扩展或计数器,覆盖的流量规模不同;
  4. 握手是否另有状态:单调时间戳或独立的报文编号,重启后是否还记得上次的值;
  5. 不要和另外两件事混写:前向保密、密钥轮换都不能从「开了重放保护」推断出来。