VPN 抓包中的错误校验和并非文件损坏
抓包可能看到的是网卡完成处理之前的报文。把分析器的结论与你收到的文件分开,并用哈希证明完整性。
分析器把一个报文标记为校验和错误,而下载的文件看起来也不对,于是两种观察被合并成一个关于 VPN 上数据损坏的说法。它们其实是在不同位置取得的不同测量。一个描述的是抓包机制在网卡完成工作之前看到的内容;另一个描述的是应用实际保存的字节。确定究竟是哪一个发生了变化,就是整个诊断。
抓包点相对于网卡的位置
抓包是在一条包含多次变换的路径上某一点的快照。在主机协议栈与网线之间,存在分段、校验和计算,以及接收时的合并。抓包点显示的是那一刻的状态,而它很少与网线上的最终帧完全一致。把它当作网线本身来读,正是一个占位字段变成指控的原因。
因此,对任何可疑字段有用的提问不是它看起来是否错误,而是它在何处被观察到。把抓包接口、分析器版本和报文层次写在结论旁边;缺少这三项,校验和标签根本无法解释。
发送卸载对追踪记录做了什么
启用发送校验和卸载时,网卡会在主机把报文排入队列之后才计算校验和并填充该字段。因此主机侧的抓包记录到的是占位值,分析器报告的校验和是网线从未携带过的。分段卸载也会造成类似现象,因为主机可以把一个大的缓冲区交给网卡,之后它才被拆成多个帧。
Wireshark 关于卸载的说明描述了这两种效应,并指出识别部分校验和取决于分析器版本和报文类型。这就是为什么较旧的抓包工具与较新的工具可能对同一条追踪记录看法不同,而两者读取的其实都正确。
封装又增加了第二个对象
VPN 在画面中插入了第二个报文。隧道接口显示的是应用真正发送的内层报文,而物理接口显示的是承载它的外层封装连接。取自内层报文的校验和或长度并不属于外层帧,把两者当作在描述同一对象来比较只会得出荒谬结论。
需要比较时,要同类相比:内层对内层、外层对外层,且在同一条路径的同一位置。不匹配的一对字段只能证明测量了两个不同的对象。记录每条追踪记录来自哪个接口,因为看起来干净的隧道抓包并不能说明网卡究竟发出了什么。
用哈希证明文件完整性
对于文件本身,分别计算可复现来源与所存结果的内容哈希,然后比较摘要。这回答的是与任何逐报文标签不同的问题,而且是针对用户真正关心的那个对象来回答的。
sha256sum payload.bin
sha256sum /srv/transfer/payload.bin
cmp -l payload.bin /srv/transfer/payload.bin | head
摘要相同,就为该次传输关闭了损坏这一疑问。摘要不同,则打开一个更窄的问题:找出字节开始分歧的最早阶段,并检查是否有东西故意转换了文件。部分保存、重新编码的附件,以及以预期文件名保存的错误页面,都会在没有任何网络故障的情况下改变字节。
定位网卡路径,但不要把它变成永久设置
对于只跟随某个扩展坞或网卡出现的可复现问题,保持 VPN 配置、应用、测试对象和目的地不变,然后通过受支持的替代接口重复传输。随网卡而改变的结果把故障定位到那条路径;它尚未指出某个驱动设置,也不能证明整个型号的缺陷。
全局关闭卸载是一个诱人的测试,却是一个糟糕的默认做法。对整个主机生效的设置会影响远超实验范围的流量,并可能带来真实的性能代价,所以要把任何此类改动当作临时措施,记录下来并予以还原。在保留从另一台机器借来的规避方案之前,先使用厂商支持的诊断手段。
报告应当说明三种结果中究竟是哪一种发生了变化:分析器对报文的解读、应用最终完成的字节,还是某条网卡路径的可复现性。它们指向三种不同的后续行动,而其中只有一种与加密有关。