网络环境:
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的问题,无法去传送任何数据。