VPN隧道中的数据包结构解析
凌晨两点十七分,某互联网公司的运维值班室。咖啡机发出最后一声叹息,屏幕上跳动的告警曲线却突然拉直——跨境专线的流量在3秒内归零。老周揉了揉发红的眼睛,抓起桌上缠着胶带的抓包工具U盘,冲向三楼核心机房。他隐约觉得,今晚要撞见某些“不该存在”的数据包。
一、隧道入口:当普通数据包穿上“防弹衣”
老周在核心交换机上做了端口镜像,Wireshark的滚动窗口立刻被密密麻麻的十六进制字符淹没。他深吸一口气,在过滤栏敲下vpn,屏幕瞬间安静下来。只剩下一串串以ESP(Encapsulating Security Payload)为协议标记的帧,像幽灵列车般在隧道里穿梭。
“看好了,”老周指着屏幕,对刚入职的小徒弟说,“这就是VPN隧道里的‘集装箱货车’。”他放大一个数据帧的头部字段:
- 外层IP头:目标地址是公司在美国机房的网关IP,端口号被刻意伪装成HTTPS的443——这是为了绕过某些防火墙的深度包检测。
- ESP头:包含一个32位的SPI(安全参数索引),像一把钥匙,告诉接收端“我是哪个安全联盟的包”。
- 加密载荷:这里才是真正的“内层数据包”——你访问的网页请求、邮件内容、甚至语音通话的RTP流,全都被AES-256算法嚼碎成密文。
“所以,外人看隧道,只能看到两个IP在互扔‘垃圾数据’。”老周敲了敲屏幕,“但隧道内部,其实是个完整的‘套娃’结构。”
二、套娃解剖:内层IP包的“三重身份”
小徒弟凑近屏幕,老周索性调出Follow TCP Stream功能,把ESP载荷解密后重组。一个完整的内层IP包浮现出来,像从俄罗斯套娃里掏出的小一号娃娃。
1. 最外层:运输标签(Transport Header)
这是“集装箱”本身。老周用Wireshark的Expert Info面板展开字段:
- 源IP:公司出口网关的私网地址(192.168.x.x)
- 目的IP:美国机房的VPN网关公网地址
- 协议号:50(ESP)
“注意这个协议号,”老周用笔尖戳着屏幕,“如果是IPsec的AH模式,协议号会是51。但AH不加密,只做完整性校验,所以现在主流都用ESP。”
2. 中层:加密信封(ESP Header + Trailer)
老周手动解析ESP的头部细节:
- SPI:0xA1B2C3D4——这是双方通过IKE协商出的随机值,相当于“暗号”。
- 序列号:32位计数器,防止重放攻击。
- 填充长度:加密算法要求数据块对齐,比如AES-256-CBC需要填充到16字节的倍数。老周指着一段
0x04 0x04:“这里填充了4个字节,填充内容也是0x04,表示‘我填充了4字节’。”
“最关键的是这个ICV(完整性校验值),”老周说,“HMAC-SHA256算出来的,放在ESP尾部。接收端解密后重新计算,如果和这个值不一致,直接丢包——这就是防篡改的‘封条’。”
3. 最内层:真实业务数据(Inner IP Packet)
老周点击Wireshark的Decode As,把解密后的明文还原。屏幕上出现一个全新的IP头:
- 源IP:员工笔记本的真实IP(10.0.0.5)
- 目的IP:美国那边服务器的地址(172.16.8.3)
- 协议号:6(TCP)
- 载荷:
GET /index.html HTTP/1.1——一个普通的网页请求。
“看到了吗?”老周把椅子转过来,“VPN的本质,就是把你原本的IP包整个塞进另一个IP包里。内层包是‘信’,外层包是‘信封’。只不过这个信封是用防弹材料做的,还上了三道锁。”
三、隧道中的“幽灵现象”:分片与重组
正当老周讲解时,告警声突然响起——一条大流量下载任务触发了MTU(最大传输单元)问题。小徒弟看着屏幕上出现的Fragmented IP标记,一脸茫然。
“这就是隧道最头疼的地方。”老周调出分片前后的对比图:
- 原始内层包:1400字节(含TCP头)
- 外层封装后:加上ESP头(8字节)+ 加密填充(16字节)+ ICV(12字节)+ 外层IP头(20字节)= 1456字节
- 物理网卡MTU:1500字节——按理说能装下,但问题是外层IP头还要加上20字节,变成1476字节,仍然小于1500,勉强能过。
“但如果内层包是1500字节的满包呢?”老周反问道。他在终端敲下ping -l 1472 -f(Windows下禁止分片),果然,返回Packet needs to be fragmented but DF set。
“这时候,VPN网关有两个选择:要么把外层包分片(违反ESP的完整性校验),要么丢弃并发送ICMP错误。”老周指着Wireshark里一个红色标记的包,“看,这个外层IP头的Fragment Offset字段是1480,说明它被切成了两片。接收端必须把两片组装起来再解密——但中间经过的防火墙可能会丢弃分片包,这就是为什么某些网络环境下VPN会突然卡死。”
“所以,好的VPN客户端会自动调整TCP MSS(最大分段大小)。”老周在命令行输入iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu,“把内层TCP的MSS从1460降到1360,给外层封装留出空间。”
四、隧道深处的“心跳”:Keepalive与NAT穿透
凌晨三点半,老周的手机震动——美国那边的同事发来消息:“隧道又断了,正在重连。”老周瞥了一眼Wireshark的统计面板,发现一个规律:每隔60秒,就有一个“空包”通过隧道。
“这是Keepalive机制。”老周指着那些长度仅为60字节的ESP包,“里面没有实际业务数据,只有ESP头和几个填充字节。它的作用是告诉对端:‘我还活着,别把隧道关了。’”
但问题出在NAT(网络地址转换)上。老周用ipsec status查看,发现公司出口的NAT设备把ESP协议(协议号50)给“遗漏”了——因为NAT只识别TCP/UDP,ESP的协议号不在映射表里。
“这就是为什么很多VPN要用UDP封装。”老周调出另一个隧道配置,“看,这个隧道用的是UDP 4500端口——IKE的NAT-T(NAT穿越)机制。它把ESP包再塞进一个UDP包里,UDP的源端口和目的端口都是4500,这样NAT设备就能正确处理了。”
他展开一个UDP封装的ESP包:
- 外层UDP头:源端口4500,目的端口4500
- 非ESP标记:UDP载荷开头有4字节的
0x00 0x00 0x00 0x00,表示“这是一个NAT-T封装的ESP包” - 真正的ESP头:紧随其后的才是SPI和序列号
“如果看到UDP载荷开头不是4个零,那可能是IKE协商包,而不是数据包。”老周补充道,“很多防火墙的深度包检测会特意检查这个标记,来识别VPN流量。”
五、隧道外的“旁观者”:如何用抓包分析VPN异常
小徒弟终于忍不住问:“师傅,那如果隧道挂了,我们怎么从抓包里定位问题?”老周笑了,他调出Wireshark的Statistics -> Flow Graph,屏幕上出现一条时间线:
- 20:00:00:IKESAINIT请求发出(UDP 500端口)——协商加密算法
- 20:00:01:响应返回,双方交换Nonce和DH公钥
- 20:00:02:IKE_AUTH请求——身份认证
- 20:00:03:创建ESP SA,SPI=0xA1B2C3D4
- 20:00:04:第一个ESP数据包发出——但立即收到ICMP端口不可达(说明对端的UDP 4500被防火墙拦截)
“看到这个ICMP错误了吗?”老周指着红色标记,“这就是隧道断开的直接原因。但更隐蔽的问题在重传——如果ESP包序列号出现跳变,比如从100直接跳到200,说明中间有设备丢包或重排序。”
他又打开Statistics -> Packet Lengths,发现大量1514字节的满包:“这是MTU问题导致的。如果看到大量TCP Previous segment lost的提示,而ESP包本身没有分片,那问题可能出在物理链路上——比如光模块衰耗过大。”
六、隧道的“另一副面孔”:WireGuard与新时代的裸包
凌晨四点,老周泡了杯浓茶,突然说:“你知道吗,现在有些新协议,根本不用ESP这种‘套娃’结构。”他打开一个WireGuard的抓包文件:
- 外层IP头:协议号是UDP(17),目的端口51820
- UDP载荷:直接是加密后的数据包,没有ESP头,也没有SPI——因为WireGuard用公钥和私钥对来标识隧道,而不是SPI。
- 消息类型:1(握手初始化)、2(握手响应)、3(传输数据)。传输数据的消息头只有4字节的Type和4字节的Receiver Index。
“WireGuard把‘隧道’这个概念简化到了极致。”老周在键盘上敲出wg show命令,“它的配置里只有公钥、私钥、IP地址和端口,没有IKE协商,没有SA生命周期,没有AH/ESP之分。每个数据包都携带一个32位的索引,直接对应接收端的加密密钥。”
“但代价是——它不支持NAT-T的自动探测,也不支持动态IP变更。”老周耸耸肩,“所以在移动网络下,WireGuard反而容易掉线。而传统的IPsec虽然笨重,但兼容性最好。”
七、隧道尽头的“黎明”:一次真实的故障修复
清晨六点,老周终于定位到问题根源:公司新换的防火墙默认丢弃了协议号50的ESP流量,只放行了UDP 500和4500。他登录防火墙,添加了一条规则:
permit esp any any
然后重启了VPN服务。Wireshark的屏幕上,ESP包重新开始流动。小徒弟看到,内层IP包里的源IP变成了他自己的电脑——他刚刚用手机热点访问了一个外网测试站。
“看到了吗?”老周摘下眼镜,揉了揉鼻梁,“隧道里的数据包,就像深夜的货运列车。外人只看到一节节黑色的车厢(外层IP),但里面装的可能是黄金、文件,或者只是一堆无用的心跳包。你要做的,就是学会用Wireshark这双‘透视眼’,看清每一层封装、每一段序列号、每一个标志位。”
“那如果遇到加密的载荷,怎么知道里面是什么?”小徒弟问。
“你不需要知道。”老周关掉Wireshark,屏幕暗下来,“VPN的意义,就是让不该知道的人永远不知道。但作为运维,你得知道隧道本身是不是健康的——这就像看心电图,你不需要听懂心脏在说什么,但你要能从波形里看出它是否在正常跳动。”
窗外天色渐亮。老周把抓包文件保存为vpn_tunnel_2025_05_18.pcapng,文件名里包含了日期和隧道ID。他站起身,拍了拍小徒弟的肩膀:“下次隧道再断,别急着重启。先抓包,看看是SPI对不上,还是序列号跳了,或者是MTU惹的祸。数据包不会说谎——它们只是穿着层层外套,等你一层层剥开。”
小徒弟盯着屏幕上定格的ESP包结构图,那些十六进制字符仿佛活了过来。他知道,这个凌晨的“隧道解剖课”,比任何文档都来得真实。而隧道里那些加密的、分片的、重传的、心跳的“幽灵数据包”,从此在他眼里有了清晰的面孔。
版权申明:
作者: 什么是VPN
链接: https://whatisvpn.net/working-principle/vpn-packet-structure.htm
来源: 什么是VPN
文章版权归作者所有,未经允许请勿转载。
上一个: VPN在多设备环境中的工作机制
热门博客
最新博客
- 防止IP泄漏的最佳设置方法
- VPN隧道中的数据包结构解析
- 不同需求下VPN选择策略详解
- VPN在多设备环境中的工作机制
- VPN隐私承诺破裂的案例分析
- 连接美国服务器VPN速度测试结果
- VPN如何帮助你获取全球新闻资讯
- 企业如何统一管理分散的办公设备
- SSL VPN是什么?和传统VPN有什么不同?
- 网络审查与法律政策关系解析
- VPN加密性能优化指南
- 未来VPN类型的发展趋势与技术演进
- VPN是否需要持续更新?如何判断?
- IPv6关闭是否可以防止IP泄漏?
- 多站点VPN网络架构解析
- Web3与网络审查的关系分析
- VPN日志记录是否可以被第三方获取
- 如何避免VPN速度被限制
- Wi-Fi环境下更容易发生DNS泄漏吗?
- 一次完整的VPN连接是如何建立的?全过程详解