家用宽带IPv6开启后上网变慢的问题

疫情隔离在家,闲来无事把家里的宽带开启了IPv6,发现上网变慢了,有时间还会出现打不开的情况。就上网google了一把,发现不是我一个人遇到这样的问题,好像很多人都是这样子,忍不了就把IPv6关了。既然都开了IPv6,就试着找找原因,看到一些文章说可能是PMTU黑洞问题。

验证一下

这里提供一个ipv6的检查工具 http://icmpcheckv6.popcount.org/ 建议在浏览器里打开这个站点,同时ssh到OpenWRT上,使用以下的tcpdum命令查看一下数据包

 1root@OpenWrt:~# tcpdump -tvvvni eth1 icmp6 and ip6[40+0]==2
 2tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
 3IP6 (flowlabel 0x4bd83, hlim 50, next-header ICMPv6 (58) payload length: 136) 2a01:7e01::f03c:91ff:fe16:a2e9 > 
 4240e:38a:86a9:be00:a182:5b65:7075:6831: [icmp6 sum ok] ICMP6, packet too big, mtu 1285
 5IP6 (flowlabel 0x4bd83, hlim 50, next-header ICMPv6 (58) payload length: 136) 2a01:7e01::f03c:91ff:fe16:a2e9 > 
 6240e:38a:86a9:be00:a182:5b65:7075:6831: [icmp6 sum ok] ICMP6, packet too big, mtu 1285
 7IP6 (flowlabel 0x4bd83, hlim 50, next-header ICMPv6 (58) payload length: 136) 2a01:7e01::f03c:91ff:fe16:a2e9 > 
 8240e:38a:86a9:be00:a182:5b65:7075:6831: [icmp6 sum ok] ICMP6, packet too big, mtu 1285
 9IP6 (flowlabel 0x4bd83, hlim 50, next-header ICMPv6 (58) payload length: 136) 2a01:7e01::f03c:91ff:fe16:a2e9 > 
10240e:38a:86a9:be00:a182:5b65:7075:6831: [icmp6 sum ok] ICMP6, packet too big, mtu 1285
11IP6 (flowlabel 0x4bd83, hlim 50, next-header ICMPv6 (58) payload length: 136) 2a01:7e01::f03c:91ff:fe16:a2e9 > 
12240e:38a:86a9:be00:a182:5b65:7075:6831: [icmp6 sum ok] ICMP6, packet too big, mtu 1285

站点页面的显示如下:

说明是有问题的,ICMP6, packet too big

我们需要把IPv6的mtu改成1280. 在wan6的配置中增加 option mtu '1280'

1vim /etc/config/network
2
3config interface 'wan6'
4        option ifname 'eth1'
5        option proto 'dhcpv6'
6        option reqaddress 'try'
7        option reqprefix 'auto'
8        option mtu '1280'

重启一下网络 /etc/init.d/network restart

再次刷新icmpcheckv6就正常了,tcpdump也看不到ICMP6, packet too big的日志了。mtu值改正之后个人体验网速与IPv4单栈的情况下没有变慢,反正有一点点的感觉被提速了 :) 也有可能是一种心理错觉。反正IPv6开启后有没有用不知道(因为我原本就有公网IPv4的地址的),个人觉得,有没有才是最重要的,就好像甲骨文云600s一样。

可能并不是所有人的OpenWRT里都有tcpdump命令的支持,OpenWRT默认编译make defconfig是没有tcpdump的,如果不会自行编译的那就自己从1432 向 1200 做 -4 偿试。如果会编译OpenWRT的,可以开启(个人建议开启,这个工具非常有用)

1Network --> 
2< * > tcpdump .......... Network monitoring and data scquisition tool

关于PMTU黑洞

MTU (Maximum transmission unit) 是一条链路上可以通过的三层数据包的最大尺寸(包含 IP 包头)。以太网上默认的 MTU 是 1500 字节,但是你和目标服务器之间的路径上可能存在小于 MTU 1500 的链路。这条路径上最小的 MTU 值就是整条路径的 PMTU 值。路由器在转发包时,超过 MTU 大小的包会被分片( Fragmentation ),也就是一个大包会被分切为多个不超过 MTU 的小包进行传输,传输效率会下降。

终端设备在发包时,也可以设置 DF ( Don't Fragment )标记来告诉路由器不要分片。这时中间路由器会丢掉超过 MTU 的包,回复一条 ICMP Fragmentation Needed 消息。发送者收到这个包后,下次就会发小一点的包,这个过程叫做 PMTU Discovery 。现实中可以看到 HTTPS ( TLS )的流量大都是带 DF 标记的。

然而,互联网上有大量的中间设备为了所谓的“安全”或者没有正确配置,不回应 ICMP Fragmentation Needed 包,这使得访问某些网站时如果某个包的大小超过了 PMTU,会被无声地丢弃,直到 TCP 协议发现超时丢包进行重传,这非常缓慢。遇到这种情况,我们可以说你和目标服务器的路径上存在 PMTU 黑洞。

此外,IPv6 不支持分片,换句话说可以理解为 IPv6 下所有的包都是带 DF 标记的。中间路由器在遇到包尺寸大于 MTU 的情况时,应该回应 ICMPv6 Packet Too Big 消息。同样的,由于种种原因,某些中间设备可能会直接丢包而不回应 ICMPv6 Packet Too Big 消息,直到 TCP 协议发现超时丢包进行重传。。。