我们的 Windows 服务器正在AAAA
向 Windows DNS 服务器注册 IPv6 记录。但是,我们的网络上没有启用 IPv6 路由,因此这经常导致停顿行为。
Microsoft RDP 是最糟糕的问题。当连接到在 DNS 中有记录的服务器时AAAA
,远程桌面客户端将首先尝试 IPv6,直到连接超时才会回退到 IPv4。高级用户可以通过直接连接到 IP 地址来解决这个问题。使用 解析 IPv4 地址总是可以ping -4 hostname.foo
立即生效。
我该怎么做才能避免这种延误?
- 在客户端上禁用 IPv6?
- 不,微软说IPv6 是 Windows 操作系统的强制性部分。
- 客户端太多,无法确保所有地方的设置都一致。
- 当我们最终实施 IPv6 时将会引起更多问题。
- 在服务器上禁用 IPv6?
- 不,微软说IPv6 是 Windows 操作系统的强制性部分。
- 需要不方便注册表黑客禁用整个 IPv6 堆栈。
- 确保所有服务器上都正确设置这一点很不方便。
- 当我们最终实施 IPv6 时将会引起更多问题。
- 在用户关心的 DNS 递归器上屏蔽 IPv6 记录?
- 不,我们使用 NLNet Unbound 和它不支持。
- 阻止在 Microsoft DNS 服务器上注册 IPv6 AAAA 记录?
- 我认为这根本不可能。
目前,我正在考虑编写一个脚本来清除我们 DNS 区域中的所有 AAAA 记录。请帮我找到更好的方法。
更新:DNS 解析是不是问题。正如@joeqwerty 在他的回答中指出的那样,DNS 记录会立即返回。A
和AAAA
记录都可以立即使用。问题是某些客户端(mstsc.exe
)将优先尝试通过 IPv6 进行连接,并需要一段时间才能恢复到 IPv4。
这看起来像是一个路由问题。ping
由于目标地址不可路由,该命令生成“常规失败”错误消息。
C:\Windows\system32>ping myhost.mydomain
Pinging myhost.mydomain [2002:1234:1234::1234:1234] with 32 bytes of data:
General failure.
General failure.
General failure.
General failure.
Ping statistics for 2002:1234:1234::1234:1234:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
我无法捕获此行为的数据包。运行此(失败的)ping 命令不会在 Microsoft 网络监视器中生成任何数据包。同样,尝试与mstsc.exe
具有记录的主机建立连接AAAA
不会产生任何流量,直到它回退到 IPv4。
更新:我们的主机都使用可公开路由的 IPv4 地址。我认为这个问题可能归结于 6to4 配置损坏。6to4 在具有公共 IP 地址和 RFC1918 地址的主机上的行为不同。
更新:我的网络上的 6to4 肯定有问题。当我在 Windows 客户端上禁用 6to4 时,连接立即解决。
netsh int ipv6 6to4 set state disabled
但正如@joeqwerty所说,这只能掩盖问题。我仍在尝试找出为什么我们网络上的 IPv6 通信完全不起作用。
答案1
这个问题非常有趣,我必须承认我从未见过这种行为。为了尝试更好地理解它,我做了一些尝试,我从另一台 W2K8R2 服务器获取了 nslookup 查询我的一台 W2K8R2 RDS 服务器的片段,并且我还从同一台测试服务器捕获了到同一台 RDS 服务器的 RDP 会话片段。Nslookup 显示返回 IPv6 记录没有延迟,nslookup 显示我的测试服务器在查询 IPv6 记录之前查询 IPv4 记录。捕获中的时间增量显示两个查询中都没有明显的延迟(我可以确定)。
编辑
现在你已经找到一些线索了。
确保您正在捕获 Microsoft 6To4 适配器的流量,否则您将看不到 IPv6:
这是我的 RDS 服务器的 nslookup 结果。记下 IPv6 地址:
下面是我捕获的片段:
最后,这是显示连接的 netstat 片段:
因此,正如您所确认的,显然 DNS 解析不是问题所在。问题在于 RDP 连接更喜欢 IPv6 而不是 IPv4(这是 Windows 的默认设置 - Windows 更喜欢 IPv6 而不是 IPv4),并且由于 IPv6 无法正常运行,因此在从 IPv6 回退到 IPv4 时会导致延迟(如您所说)。您可以通过将客户端配置为更喜欢 IPv4 而不是 IPv6 来解决这个问题,但我认为这只会掩盖问题。更好的解决方案是找出 IPv6 无法正常工作的原因并解决它。我对 IPv6 了解不够,无法提供帮助,但我的猜测是 DNS 返回的 IPv6 记录是仅在 RDS 主机所在的子网上有效的“本地”地址,并且由于客户端位于不同的子网中,因此它们无法访问这些 IPv6 地址。
答案2
IPv6 过渡技术(6to4)臭名昭著导致此类问题的原因有很多。有几个因素在起作用。这些因素单独来看是无害的,但综合起来看,最终用户可能会遇到连接延迟。
下面列出了一些促成因素以及缓解这些因素的想法。
Windows 默认启用 6to4
如果您的主机运行的是较新版本的 Windows(Vista 或更高版本),当有可公开路由的 IPv4 地址可用时,Windows 会适时启用 6to4 隧道。重要的是,这适用于服务器和客户端。
要确定系统是否正在使用 6to4,请运行ipconfig
并查找以 6to4 前缀开头的 IPv6 地址2002:
。它看起来像这样。
C:\> ipconfig
Tunnel adapter 6TO4 Adapter:
IPv6 Address. . . . . . . . . . . : 2002:1111:2222::1111:2222
- 如果您的终端连接到 Active Directory,则可以使用组策略禁用 6to4 和 Teredo 等转换协议。这在KB929852(将此应用到您的客户端或服务器就足够了,但如果您要采取这一步骤,则在两个客户端上都禁用它可能是有意义的和服务器。
- 如果你只管理少数主机,你可以根据具体情况禁用 6to4。这比完全禁用 IPv6 要好得多。
netsh int ipv6 6to4 set state disabled
- 使用不同的客户端操作系统。例如,Mac OS X 默认不启用 6to4。
正在使用可公开路由的 IPv4 地址
6to4 仅适用于具有公共可路由 IPv4 地址的主机,因此此问题不会影响 NAT 防火墙后面的主机。
- 您可以将客户端和/或服务器移到 NAT 防火墙后面,并开始使用 RFC1918 寻址。但在某些情况下,公共可路由地址实际上是首选。更改整个网络的寻址也可能是不切实际的选择。
6to4 在网络上无法正常运行
在任播模式下排除 6to4 故障非常困难。它非常麻烦,以至于有人向 IETF 正式提出请求,6to4 应重新归类为历史. 在本文作者看来,6to4 已被弃用。
简而言之,6to4 的工作原理是使用名为 6in4(IP 协议 = 41)的协议将 IPv6 数据包封装到 IPv4 数据包中。IPv4 数据包被发送到任播地址,192.88.99.1
希望它能够到达互联网上某个正常工作的 6to4 中继。如果你够幸运的话,它甚至可能在地理位置上很近。
实际上,一些 6to4 中继设置不正确,许多网络甚至不允许 6in4 流量穿过防火墙。通常,当防火墙允许所有出站流量,但没有明确允许 IP 协议 41 数据包通过防火墙返回时,就会发生这种情况。(TODO 请参阅相关的 RFC 以进行故障排除。)此故障(“入站黑洞”)和许多其他故障在RFC 6343。
- 设置防火墙,当从网络内部的主机发送 IP 协议 41(使用 TCP 重置)时,大声拒绝该协议。这应该会导致“快速失败”行为,这比非确定性连接延迟更有意义。这已经已证明在有限的测试环境中有效。
- 要求您的 ISP 或首跳传输提供商设置有效的 6to4 中继。如果操作正确,将为最终用户带来最佳体验。任何拥有可公开路由的 IPv4 地址的最终用户都可以参与 IPv6 互联网。
动态 DNS 注册
在典型的 Active Directory 环境中,每台计算机都可以向 DNS 服务器注册自己的地址。当主机是多宿主主机时,它将注册其所有地址,即使是来自 6to4 隧道的地址。
大多数互联网服务不使用动态 DNS,因此该问题通常仅限于客户端和服务器都位于同一网络“内部”的企业站点。
- 您可以选择禁用动态 DNS 更新。这样,如果您不将任何 AAAA 资源记录放入区域文件,它们将永远不会被提供。但是,动态 DNS 通常是内部 DNS 服务器的理想选择。(如果您这样做,请确保删除可能已经存在的任何 AAAA 记录。)
- 将 DNS 服务器设置为不提供 AAAA 资源记录的答案。但不要这样做,因为当您想要开始实施 IPv6 时,这确实会给您带来麻烦。(有人知道免费/开源 DNS 防火墙吗?)
客户端应用程序无法正常失败
微软的 RDP 客户端就是一个不能很好地处理 IPv6 路由问题的客户端应用程序的例子。大多数网络浏览器都更擅长处理类似这样的 IPv6 边缘情况,因此它们往往不会表现出这种行为。
- 尝试使用不同的客户端。也许你会幸运。
答案3
我知道这对于这种情况没有什么帮助,但对于面临类似困境的实施者来说,有一种称为“快乐眼球”(RFC 6555)指定了一种同时连接 IPv4 和 IPv6 并选择首先连接的技术。
答案4
这是我的解决方案。默认情况下,Windows 为 IPv6 路由赋予比 IPv4 路由更高的优先级。如果您编辑 IPv6 前缀策略,则可以更改此行为以使其优先使用 IPv4 而不是 IPv6。
为了确保我的网络中的所有系统都以相同的方式设置,我将以下命令放入在构建或翻新机器后在软件安装期间运行的 .bat 脚本中。
netsh int ipv6 isatap set state disabled
netsh int ipv6 6to4 set state disabled
netsh interface teredo set state disable
netsh interface ipv6 delete prefixpolicy ::1/128
netsh interface ipv6 delete prefixpolicy ::/0
netsh interface ipv6 delete prefixpolicy 2002::/16
netsh interface ipv6 delete prefixpolicy ::/96
netsh interface ipv6 delete prefixpolicy ::ffff:0:0/96
netsh interface ipv6 delete prefixpolicy 2001::/32
netsh interface ipv6 add prefixpolicy ::1/128 50 0
netsh interface ipv6 add prefixpolicy ::ffff:0:0/96 40 1
netsh interface ipv6 add prefixpolicy ::/0 30 2
netsh interface ipv6 add prefixpolicy 2002::/16 20 3
netsh interface ipv6 add prefixpolicy ::/96 10 4
netsh interface ipv6 add prefixpolicy 2001::/32 5 5
解释一下这个是做什么的:
前 3 行禁用内置隧道接口,因为它们对于大多数网络而言都是多余的。如果您没有为机器提供自己的 IPv6 地址,则可能不想使用这 3 行,在我的例子中,我有一个 DHCPv6 服务器和相关基础设施,为隧道连接分配 IPv6
第二组命令删除所有现有的 IPv6 路由前缀策略。
然后,第三个块重新创建 IPv6 前缀策略,但使用一组不同的优先级。因此,与 IPv4 对应的前缀优先于 IPv6,并且除非应用程序指定使用 IPv6,否则机器将希望使用 IPv4。
该解决方案保留了功能性的双栈能力,但优先使用 IPv4 意味着 IPv6 不完整、不可靠或性能较差的站点将避免使用它,除非系统上的程序指示这样做。
我认为让操作系统优先使用 IPv6 而不是 IPv4 实际上是在阻碍 IPv6 的采用。在过渡期间,有时主机会认为它具有 IPv6 连接,但实际上并没有完全正常运行的连接,从而导致软件故障和长时间延迟。我认识的许多人都在他们的路由器上完全禁用了 IPv6,作为 ISP 在建立完全连接之前最初以不完善的方式部署 IPv6 的解决方法,这些人会忘记再次启用它,直到他们重新配置路由器后才能使用 IPv6。