在 nat 网络下 mtu 设置错误,会导致 linux 的 vpn 无法正常发送 tcp 数据包。

2014-08-07 07:13:15 +08:00
 tywtyw2002
网络环境:
a b 两台服务器用gre over ipsec去连接,数据包从b服务器nat出去。

问题:
两台服务器ping对端都正常,a 访问b服务器上的网站也是正常。
但是a去访问公网就出现了问题,tcp无法获取数据。但是udp没问题。

解决方案:
1. 在 a 和b上面同时在gre隧道上面抓包,发现数据包都没问题,并且数量一致 --- 所以隧道本身没有问题。
2. 在b服务器上看nat的数据包计数(用iptables去看),发现nat数据包的数量小于在gre隧道中实际发送的数据包数量 ---nat过程中发生了丢包。
3. 仔细查看tcpdump的报文,居然是0. 证明在nat中丢包的。

22:39:34.411660 IP 101.227.172.11.http > 172.20.0.1.56383: Flags [.], ack 320, win 7, length 0
22:39:34.411862 IP 101.227.172.11.http > 172.20.0.1.56383: Flags [P.], seq 1437:1438, ack 320, win 7, length 1
22:39:34.411880 IP 172.20.0.1.56383 > 101.227.172.11.http: Flags [.], ack 1, win 57, length 0
22:40:05.686723 IP 172.20.0.1.39960 > 101.227.172.11.http: Flags [F.], seq 2634048859, ack 1869457481, win 57, length 0
22:40:06.580564 IP 172.20.0.1.39960 > 101.227.172.11.http: Flags [F.], seq 0, ack 1, win 57, length 0
22:40:08.368559 IP 172.20.0.1.39960 > 101.227.172.11.http: Flags [F.], seq 0, ack 1, win 57, length 0
22:40:11.944613 IP 172.20.0.1.39960 > 101.227.172.11.http: Flags [F.], seq 0, ack 1, win 57, length 0
22:40:19.096548 IP 172.20.0.1.39960 > 101.227.172.11.http: Flags [F.], seq 0, ack 1, win 57, length 0
22:40:33.400558 IP 172.20.0.1.39960 > 101.227.172.11.http: Flags [F.], seq 0, ack 1, win 57, length 0
22:41:02.008574 IP 172.20.0.1.39960 > 101.227.172.11.http: Flags [F.], seq 0, ack 1, win 57, length


4.在出口抓包,发现了对方服务器发送过来的ICMP包,包的内弄是 数据包需要分片。---原因在这里 mtu的问题 默认mtu是14700,但是实际mtu只能是1396造成了数据包分片。


解决:
把a b服务器的隧道的mtu改成了 1396就好了。

解析:
问题出在,nat不能把icmp数据包给nat回来,因为这个数据包是多余的,根据nat的概念,a服务器永远收不到这个icmp数据包,所以tcp链接的win一直是0。而b服务器就直接忽略了这个icmp数据包,所以tcp一直是通的,但是因为mtu的问题,无法去传送任何数据。
4914 次点击
所在节点    Linux
1 条回复
zhanglp888
2014-08-07 13:47:35 +08:00
我也有同样问题,我的A在国内,B在国外,我一直认为是墙在作怪

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/126495

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX