分类: 架构设计与优化
2022-11-28 16:43:26
导语
VPN是一种通过公网连接两个或多个私网站点的专用网络,使得这些站点仿佛是通过专线连接在一起。IPSec是一套协议框架,用于保证数据传输的私密性,完整性,真实性。但是VPN网络经常会带来一些连通性上的问题,通常与MTU设置的不合理有关。本文通过一个实际案例,来具体分析解决这个问题。
作者:陆信宇
一、环境拓扑
1.链路中,各个设备接口的MTU为1450
MTU是数据链路层的概念,限制的是数据链路层payload的大小,即上层协议大小(包括上层协议头),例如设置主机接口mtu为1450。则在一个TCP报文中,1450 = 20字节IP头 + 20字节TCP头 + 1410TCP数据。
2.RDS为京东智联云云数据库实例,实例中创建有400个数据库。
3.SH_MariaDB_VM是一台上海地域的云主机,部署了mariadb服务,数据和RDS实例相同。
4.BJ_VPNGW和SH_VPNGW分别是北京VPC和上海VPC的vpn网关
5.bj_client所在子网和RDS所在子网通信时,下一跳为各自所在地域的vpn网关
二、现象描述
三、排查过程
四、问题原因
由于bj_client、RDS、SH_MariaDB_VM的mtu都是1450,所以bj_client与RDS、SH_MariaDB_VM进行TCP三次握手时,协商的MSS大小为1410(MTU - 20B ip头 - 20B tcp头)。即后续发送的TCP报文的数据部分,{BANNED}最佳大不能超过1410字节,且IP头中DF置位,不允许报文分片。
bj_client连接RDS执行show databases命令。由于请求包较小,所以请求报文可以正常通过vpn网关到达RDS。RDS收到报文后开始响应。由于RDS中数据库很多,所以响应报文会拆分成多个进行发送,每个报文的TCP数据部分是1410字节。报文到达VPN网关后,VPN网关在原数据包基础上再次封装ESP、UDP、IP,封装之后的报文大小超过了VPN网关出接口的mtu值,又因为数据包不允许分片,导致VPN网关丢弃报文。VPN网关丢弃报文之后,会向RDS发送一个ICMP Error,指明mtu of next hop: 1374 ,告知RDS以1374为{BANNED}最佳大mtu发包。但是因为RDS实例前面还有一层LB,且这个LB不会转发ICMP Error报文,导致ICMP Error报文并没有到达真正的RDS服务端,{BANNED}最佳终导致RDS没有调整数据包大小就直接重传,数据包再次被vpn网关丢弃,进入死循环。
五、解决方案
根据以上分析,有三种解决方法。
六、其他
1 什么是MTU
MTU是数据链路层的概念,限制的是数据链路层payload的大小,即上层协议大小(包括上层协议头)
例如设置主机接口mtu为1450。则在一个TCP报文中,1450 = 20字节IP头 + 20字节TCP头 + 1410TCP数据。
2 什么是MSS
MSS{BANNED}最佳大报文段,是TCP中一个选项,用于在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的{BANNED}最佳大数据长度(注意不包含TCP头部大小)
3 如何探测路径MTU值
Linux主机中: 执行ping x.x.x.x -s 1422 -M do ,x.x.x.x是目标地址,-s指明icmp报文的数据部分大小(不包含icmp 8字节头部)。-M do 表示不允许分片。多试几次,找到临界点。以mtu为1450为例,1450 = 20字节IP头 + 8字节icmp头 + 1422数据,则-s指定为1422可以正常通过
Windows主机中: 执行ping x.x.x.x -l 1472 -f ,x.x.x.x是目标地址,-l指明icmp报文的数据部分大小(不包含icmp 8字节头部)。-f表示不允许分片。
4 如何查看MTU
Linux: ifconfig
windows: netsh interface ipv4 show subinterfaces
5 如何设置MTU
Linux: ifconfig eth0 mtu xxx
windows: netsh interface ipv4 set subinterface "WLAN" mtu=1450 store=persistent