这让我抓狂,因为我无法仅从 KVM 虚拟机且仅通过 IPv6 加载某些 HTTPS 网站。 IPv4 工作正常。 IPv6 连接适用于虚拟机管理程序中的相同网站。
我的设置
- KVM 虚拟机管理程序运行在Ubuntu 14.04.5 LTS。
- 以太网0被添加到br0桥接口,我使用这个桥将虚拟机连接到外部世界。
- 两个虚拟机在虚拟机管理程序上运行。第一个正在运行乌班图12.04(我知道它已经达到 EOL,但这并不重要),第二个是乌班图16.04。两个虚拟机遇到问题。
- VM 使用 Virtio 接口连接到网络。
- IPv6 地址由虚拟机管理程序和虚拟机获取。
- 如果域支持,我的 DNS 服务器将返回 IPv6 地址,否则它适用于 IPv4。
我没有针对 IPv6 的防火墙(ip6tables),无论是虚拟机管理程序还是虚拟机。
# ip6tables -v -L -n Chain INPUT (policy ACCEPT 196K packets, 32M bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 5007K packets, 3858M bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 185K packets, 30M bytes) pkts bytes target prot opt in out source destination # ip6tables -v -L -n -t nat Chain PREROUTING (policy ACCEPT 1749 packets, 181K bytes) pkts bytes target prot opt in out source destination Chain INPUT (policy ACCEPT 135 packets, 24165 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 187 packets, 27578 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 1801 packets, 185K bytes) pkts bytes target prot opt in out source destination
问题
IPv6(和 IPv4)连接适用于虚拟机管理程序中的所有网站(这很好并且符合预期)。
# wget https://lwn.net -O - > /dev/null; echo Exit code: $? --2017-08-02 18:55:47-- https://lwn.net/ Resolving lwn.net (lwn.net)... 2600:3c03::f03c:91ff:fe61:5c5b, 45.33.94.129 Connecting to lwn.net (lwn.net)|2600:3c03::f03c:91ff:fe61:5c5b|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 25202 (25K) [text/html] Saving to: ‘STDOUT’ 100%[=====================================>] 25,202 149KB/s in 0.2s 2017-08-02 18:55:48 (149 KB/s) - written to stdout [25202/25202] Exit code: 0
IPv6 连接适用于我在虚拟机内部尝试过的大多数网站,但并非全部。例如,https://lwn.net和https://hioa.no我在使用两个 https 网站时遇到了问题。从下面的wget命令可以看到,连接到达了连接的状态但它卡在那里:
# wget https://lwn.net -O - > /dev/null; echo Exit code: $? --2017-08-02 18:53:40-- https://lwn.net/ Resolving lwn.net (lwn.net)... 2600:3c03::f03c:91ff:fe61:5c5b, 45.33.94.129 Connecting to lwn.net (lwn.net)|2600:3c03::f03c:91ff:fe61:5c5b|:443... connected.
到目前为止我已尝试解决该问题
从 ping6 开始。有趣的是,使用 IPv6 时,来自虚拟机的 ping 操作适用于所有域!包括https不起作用的。
# ping6 -c 1 -n hioa.no PING hioa.no(2001:700:700:2::65) 56 data bytes 64 bytes from 2001:700:700:2::65: icmp_seq=1 ttl=53 time=88.7 ms # ping6 -c 1 -n lwn.net PING lwn.net(2600:3c03::f03c:91ff:fe61:5c5b) 56 data bytes 64 bytes from 2600:3c03::f03c:91ff:fe61:5c5b: icmp_seq=1 ttl=54 time=145 ms
我尝试更改虚拟网络设备虚拟机到e1000。问题仍然存在。
尝试使用 IPv4 连接到我遇到问题的网站。
# dig A lwn.net ; <<>> DiG 9.10.3-P4-Ubuntu <<>> A lwn.net ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41423 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;lwn.net. IN A ;; ANSWER SECTION: lwn.net. 2633 IN A 45.33.94.129
IPv4 连接工作正常!
# wget --no-check-certificate https://45.33.94.129 -O - > /dev/null; echo Exit code: $? --2017-08-02 18:41:32-- https://45.33.94.129/ Connecting to 45.33.94.129:443... connected. WARNING: certificate common name `*.lwn.net' doesn't match requested host name `45.33.94.129'. HTTP request sent, awaiting response... 200 OK Length: 25226 (25K) [text/html] Saving to: `STDOUT' 100%[==================================>] 25,226 137K/s in 0.2s 2017-08-02 18:41:33 (137 KB/s) - written to stdout [25226/25226] Exit code: 0
尝试使用“openssl s_client”进行连接并查看是否有任何错误消息,但“openssl s_client”尚不支持IPv6(至少在Ubuntu 16.04中包含的openssl版本中不支持)。
已检查消息和/var/log/系统日志但那里没有任何相关的东西。
任何人都知道为什么我在某些网站上会出现这种奇怪的行为?关于我接下来应该尝试调查什么的任何指示?
答案1
通过将虚拟机中的 MTU 减少到 1492 解决了问题。 hypervisor 负责建立到互联网的 PPPoE 连接,ppp0 接口的 MTU 为 1492 字节。
既然 IPv4 和 IPv6 都实现了路径 MTU 发现,为什么 MTU 会成为问题呢?那么为什么路径 MTU 发现在这种情况下不起作用(仅适用于某些 IPv6 目的地)?
好像我遇到了一个黑洞这里的情况。
我使用 Wireshark 捕获了一些流量tcpdump
并加载了文件。我观察到连接通过 TCP 三向握手,如附图(数据包 1-3)所示。从我的问题的输出中也可以看出这一点wget
,您可以看到 wget 在打印connected
消息后卡住了。成功三向握手后,客户端(我的虚拟机)发送 SSL《客户您好》消息但从未收到“服务器你好”后退。客户端收到的是一个数据包,根据 TCP 序列号,该数据包显然是无序的(wireshark 也报告[TCP 上一段未捕获],连续数据)。然后,客户端对已收到的最后一个有序数据包(重复的 ACK)使用 ACK(数据包 6)进行响应,并且由于服务器尝试重新发送该数据包,因此连接停止丢包它大于支持的 MTU 并且永远不会到达。因此,连接会卡在那里,直到我按Ctrl+C启动连接终止(数据包 8-10)。
那么,为什么路径 MTU 发现不仅适用于某些 IPv6 目的地(并非全部),而对 IPv4 却完全没有问题呢?对于这个问题,由于我的安装没有 IPv6 防火墙,我假设在通往某些网站的途中有一些防火墙阻止了ICMPv6 数据包太大消息路径 MTU 发现工作所需的。有趣的是,简单的 ICMPv6 ping 数据包会通过,我什至会收到回复。