导语

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网关

二、现象描述

  1. bj_client通过BJ_VPNGW连接RDS。执行show databases时,一直卡住无返回。

  2. bj_client通过BJ_VPNGW连接SH_MariaDB_VM。执行show databases正常,没有卡住的现象。

三、排查过程

  1. bj_client可以ping通RDS,telnet RDS 3306端口正常,使用mysql客户端也可以正常连接。

  2. 在BJ_VPNGW和SH_VPNGW上抓包分析。发现RDS回包正常到达SH_VPNGW,但是没有到达BJ_VPNGW。数据包在SH_VPNGW被丢弃。怀疑是MTU问题,导致丢包。

  3. 继续抓包分析RDS和SH_MariaDB_VM回包的区别。发现SH_VPNGW都给RDS和SH_MariaDB_VM回了一个IMCP Error报文,报文中指定了MTU next hop: 1374。但是RDS的重传报文中,ip层的Total Length一直是1450。SH_MariaDB_VM在首次被丢包后,重传报文的Total Length为1374。判断ICMP Error报文没有被正常转发给RDS服务端。后核实RDS前面还有一层LB,该LB没有转发ICMP Error。

  4. 调整bj_client接口mtu为1374之后,问题解决。

四、问题原因

由于bj_client、RDS、SH_MariaDB_VM的mtu都是1450,所以bj_client与RDS、SH_MariaDB_VM进行TCP三次握手时,协商的MSS大小为1410(MTU - 20B ip头 - 20B tcp头)。即后续发送的TCP报文的数据部分,最大不能超过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为最大mtu发包。但是因为RDS实例前面还有一层LB,且这个LB不会转发ICMP Error报文,导致ICMP Error报文并没有到达真正的RDS服务端,最终导致RDS没有调整数据包大小就直接重传,数据包再次被vpn网关丢弃,进入死循环。

五、解决方案

根据以上分析,有三种解决方法。

  1. 调小服务端或者客户端mtu,让两端在建立三次握手协商mss时,以更小的mss收发数据。可以设置为ping探测的路径MTU值。

  2. 在VPN网关配置iptables -t mangle -A FORWARD -o eth0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu。两端建立三次握手的报文到达vpn网关时,修改MSS值,使MSS自适应PMTU(Path MTU)

  3. 保证icmp error报文可达

六、其他

  1. 什么是MTU

    MTU是数据链路层的概念,限制的是数据链路层payload的大小,即上层协议大小(包括上层协议头)

    例如设置主机接口mtu为1450。则在一个TCP报文中,1450 = 20字节IP头 + 20字节TCP头 + 1410TCP数据。

  2. 什么是MSS

    MSS最大报文段,是TCP中一个选项,用于在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度(注意不包含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

一次MTU问题导致的RDS访问故障的更多相关文章

  1. ooofc.com域名备案问题导致无法正常访问临时解决方案

    各位尊敬的easyradius用户: 由于临时收到ooofc.coom域名备案被删除的消息,之后ooofc.com就无法访问.导致用户无法访问控制台oa.ooofc.com,及用户中心user.ooo ...

  2. [svc]mount命令及解决因/etc/fstab错误导致系统不能启动故障

    mount命令-手动挂载设备 格式: mount [options] [-t fstype] [-o option] 设备 挂载点 mount -n -o remount,rw / - Mount t ...

  3. Linux索引节点(Inode:no space for device)用满导致的一次故障

    问题描写叙述 在storm測试环境集群上上nimbus和supervisor自己主动挂调.重新启动时显示no space for device,也不能创建,加入文件及文件夹,df -h查看 ilesy ...

  4. 【故障公告】再次遭遇SQL语句执行超时引发网站首页访问故障

    非常抱歉,昨天 18:40~19:10 再次遭遇上次遇到的 SQL 语句执行超时引发的网站首页访问故障,由此您带来麻烦,请您谅解. 上次故障详见故障公告,上次排查下来以为是 SQL Server 参数 ...

  5. 一次由于 MTU 设置不当导致的网络访问超时

    转自:http://weibo.com/ttarticle/p/show?id=2309404140904511340923 API 服务正常,但是调用总是超时.api端日志显示,响应速度很快. ​​ ...

  6. 更改apache网站根目录导致localhost不能访问

    使用xampp或wamp安装完集成环境后,更改apache的网站根目录会导致localhost,localhost/phpmyadmin访问不到. 解决方法: 打开apache的配置文件:“../ap ...

  7. 解决ASP.NET MVC AllowAnonymous属性无效导致无法匿名访问控制器的问题

    在ASP.NET MVC项目中,一般都要使用身份验证和权限控制,但总有部分网页是可以匿名访问的.使用AllowAnonymous属性就可以指定需要匿名访问的控制器,从而跳过身份验证. 但是今天却遇到一 ...

  8. 路由器子网掩码设置不正确导致github无法访问

    奇怪的现象,路由器子网掩码设置成255.0.0.0会导致电脑访问不到https://github.com/ 改成默认的255.255.255.0就正常了.

  9. 防火墙导致MySQL无法访问的问题解决案例

    问题 数据库总是访问不了以致不得不反反复复的重启MySQL数据库. 但是重启的效果并不明显,重启10几分钟后问题依然出现.导致前端用户难以正常访问网站.另外他们还通过google,百度搜索,怀疑是数据 ...

  10. iis 故障导致网站无法访问

    服务器使用两三个月突然,昨天无法访问,重启后正常,第二次发生这样的事情了,打开  C:\WINDOWS\system32\LogFiles\HTTPERR  下的   httperr1.txt 201 ...

随机推荐

  1. 面试突击83:什么情况会导致@Transactional事务失效?

    一个程序中不可能没有事务,而 Spring 中,事务的实现方式分为两种:编程式事务和声明式事务,又因为编程式事务实现相对麻烦,而声明式事务实现极其简单,所以在日常项目中,我们都会使用声明式事务 @Tr ...

  2. Netty 学习(三):通信协议和编解码

    Netty 学习(三):通信协议和编解码 作者: Grey 原文地址: 博客园:Netty 学习(三):通信协议和编解码 CSDN:Netty 学习(三):通信协议和编解码 无论使用 Netty 还是 ...

  3. Python实验报告——第4章 序列的应用

    实验报告 [实验目的] 1.掌握python中序列及序列的常用操作. 2.根据实际需要选择使用合适的序列类型. [实验条件] 1.PC机或者远程编程环境. [实验内容] 1.完成第四章 序列的应用 实 ...

  4. Django环境安装

    1.安装Django # 自动安装PyPi提供的最新版本 pip install django # 安装指定版本 pip install django==2.2 # 验证安装 >>> ...

  5. 3.使用nexus3配置maven私有仓库

    配置之前,我们先来看看系统默认创建的都有哪些 其中圈起来的都是系统原有的,用不到,就全删掉,重新创建. 1,创建blob存储 2,创建hosted类型的maven 点击 Repository下面的 R ...

  6. 记录阿里云安全组设置遇到的奇葩问题--出口ip

    之前公司使用的路由器里使用的是PPPOE拨号的形式上网的,根据拨号后得到的ip地址,配置到阿里云的安全组里,具体来说是配置到22端口里,也就是说只有特定ip才能访问22端口,也即是说只允许公司网络远程 ...

  7. day05-离线留言和离线文件

    多用户即时通讯系统05 4.编码实现04(拓展) 拓展功能: 实现离线留言,如果某个用户不在线 ,当登陆后,可以接收离线的消息 实现离线发文件,如果某个功能没有在线,当登录后,可以接收离线的文件 4. ...

  8. Go设计模式学习准备——下载bilibili合集视频

    需求 前段时间面试,被问到设计模式.说实话虽然了解面向对象.多态,但突然被问到设计模式,还要说清解决什么问题,自己是有些懵的,毕竟实习主要工作是在原项目基础进行CRUD,自己还是没有深度思考,所以只能 ...

  9. scss的使用方法

    引用scss文件--看上一篇的less使用,里面的Koala,一样的原理!!! 方法一: scss: /**定义变量 */$width:404px;$color:green;$font-size:20 ...

  10. Hyperf使用ElasticSearch记录

    Hyperf 安装 Elasticsearch 协程客户端 hyperf/elasticsearch 主要为 elasticsearch-php 进行了客户端对象创建的工厂类封装,elasticsea ...