服务器

虚拟专用网(VPN)之无法访问百度之谜

不久前开了个香港Sunny Vsion的VPN,平时我一般都不使用VPN,今天才发现无法访问百度,而尝试其他网站却正常,遂探讨了一番。

我使用的都是学校的中国电信网络,本地连接VPN后,访问百度网站无任何回应,在服务器上可以成功地使用curl对百度发起请求,检查了iptables,未发现任何问题。

既然服务器能访问,那么理论上VPN也有权访问,但现在却与理论背道而驰。为了找出问题的根源,搬出抓包神器——tcpdump。

首先我在服务器上抓取本地分别透过VPN访问cPanel/WHM的208.74.0.0/16与百度的103.235.46.39/32的数据包,以作对比,查找错误。

cPanel/WHM:

百度:

首先,在两边的记录,都可以看到Flags [P.],这是开始传输内容的标记,因此可以肯定,我们本地与百度之间的TCP三次握手是顺利地完成了的,不然也就不会开始传输数据。

在与cPanel/WHM服务器通讯时,看到了Flags [F.],这是完成数据传输,结束TCP连接的标记。

但是在百度却没看到Flags [F.],可以看到103.235.46.39发送了很多类似seq 1:1063的数据包,但是我们本地仅返回了ack 1063给百度,根据TCP协议,ack的可以理解为“确认收到”,ack 1063,那就是说我们本地告诉百度的服务器确认收到了seq 1:1063的数据包。

TCP是一个可靠的协议,之所以说可靠,是因为服务器会重新发送客户端没有收到的数据包,可以保障数据的完整性,既然我们本地仅返回了ack 1063,百度服务器很自然就会重发我们没收到的数据包,也就对应了百度那边的抓包结果最后面的seq 1063:2515。

总算找到方向了:我们本地可能没有完整地收到百度发送的所有数据包!

为了确定我们本地是否真的没有收到数据包,我再次访问百度,并进行了双边抓包:

本地:

服务器:

服务器完完整整地收到了百度发送的数据包,我们本地收到了seq 1:1062,但下一个seq是6870:8262,再下一个居然是18426:19782!这丢包率真把我给吓坏了……

赶紧从本地MTR到服务器看看:

MTR To Server

然后走VPN MTR到百度看看:

MTR To BAIDU via VPN

虽然MTR可以看到有少量丢包,不过这丢包率完全不符合我TCPDUMP的结果,这说明这丢包根本不是线路不佳造成的。

完全不服……

想起来之前在家研究广电机顶盒时,遇到过桥架网卡后因为其中一个网卡MTU非1500(桥接后,桥接网卡的MTU不能大于MTU最小的网卡的MTU)而导致PPPOE连接成功却打不开网页的情况。

MTU是什么不在此长篇大论,至于为什么要减掉一部分数值,是构建了虚拟隧道的问题,数据包进入虚拟隧道前,还是要封装成适合进入这个虚拟隧道的类型的,因此数据包体积会比原来大,具体细节,不在此长篇大论,各位有兴趣可以通过搜索引擎了解。

更好服务器上也用桥接网卡,于是看了下br0(桥接网卡), eth0(物理网卡)和服务器与我本地通讯的ppp1的MTU:

MTU

br0和eth0都是1500, ppp1是1496,我本地的ppp也是1496。

看起来是非常正常且毫无问题的,因为默认情况下VPN构建的ppp的MTU都是1496这个值……

不过既然是非线路问题导致的丢包,改改MTU也无妨,于是分别在服务器和本地都把VPN构建的ppp的MTU改成1400:

再次curl百度:

CURL BAIDU

是成功地连上了……

不过我之前都在未桥架的服务器上搭建VPN,为了探究清楚是桥架还是该服务器的网络环境的问题,我又在另一台使用了桥架的服务器搭建了VPN并访问百度: CURL BAIDU USA

还好是成功的,ppp的mtu同样是1496,这就说明了这个问题在这次与桥接不沾边,是这台Sunny Vision服务器的问题。

虽然最后成功解决了无法打开百度(现在应该是说比较大的网页)的问题,但最大的问题是,目前为止,对于是何导致了此服务器无法使用1496,我还没有任何思绪……

才疏学浅啊,若各位有见解,请告知一下……