AAAA
我们的 Windows 服务器正在向我们的 Windows DNS 服务器注册 IPv6记录。但是,我们的网络上没有启用 IPv6 路由,因此这经常会导致停顿行为。
Microsoft RDP 是最严重的违规者。当连接到在 DNS 中有AAAA
记录的服务器时,远程桌面客户端将首先尝试 IPv6,并且在连接超时之前不会回退到 IPv4。高级用户可以通过直接连接到 IP 地址来解决此问题。ping -4 hostname.foo
使用总是立即解析 IPv4 地址。
我能做些什么来避免这种延迟?
- 在客户端上禁用 IPv6?
- 不,微软表示IPv6 是 Windows 操作系统的必需部分。
- 太多的客户无法确保在任何地方都始终如一地设置。
- 当我们最终实现 IPv6 时,会引起更多的问题。
- 在服务器上禁用 IPv6?
- 不,微软表示IPv6 是 Windows 操作系统的必需部分。
- 需要一个不方便的注册表黑客来禁用整个 IPv6 堆栈。
- 确保在所有服务器上都正确设置是不方便的。
- 当我们最终实现 IPv6 时,会引起更多的问题。
- 屏蔽用户 facnig 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 通信完全不起作用。
这个问题很有趣,我必须承认我从未见过这种行为。在进行一些尝试以更好地理解它时,我从另一个 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 主机所在的子网上有效,并且由于客户端位于不同的子网中,因此它们可以t 到达那些 IPv6 地址。
称为 6to4 的 IPv6 过渡技术因引发此类问题而臭名昭著。有几个因素在起作用。单独它们是无害的,但综合效果是最终用户可能会遇到连接延迟。
下面列出了促成因素及其缓解措施的想法。
Windows 默认启用 6to4
如果您的主机运行的是最新版本的 Windows(Vista 或更高版本),Windows 将在可公开路由的 IPv4 地址可用时适时启用 6to4 隧道。至关重要的是,这适用于服务器和客户端。
要确定系统是否使用 6to4,请运行
ipconfig
并查找以 6to4 前缀开头的 IPv6 地址2002:
。它看起来像这样。netsh int ipv6 6to4 set state disabled
正在使用可公开路由的 IPv4 地址
6to4 仅适用于具有可公开路由的 IPv4 地址的主机,因此此问题永远不会影响 NAT 防火墙后面的主机。
6to4 在网络上无法正常运行
在任播模式下对 6to4 进行故障排除是出了名的困难。麻烦的是,IETF 正式要求将6to4 重新归类为历史性的。在作者看来,6to4 已被弃用。
简而言之,6to4 的工作原理是使用称为 6in4(IP 协议=41)的协议将 IPv6 数据包封装成 IPv4 数据包。IPv4 数据包被寻址到任播地址
192.88.99.1
,希望它能够到达 Internet 上某个工作的 6to4 中继。如果幸运的话,它甚至可能在地理位置上就在附近。在实践中,一些 6to4 中继设置不正确,很多网络甚至不允许 6in4 流量穿过防火墙。通常,当防火墙允许所有出站流量,但未明确允许 IP 协议 41 数据包通过防火墙返回时,就会发生这种情况。(TODO 请注意相关的 RFC 以进行故障排除。)此故障(“入站黑洞”)和许多其他故障在RFC 6343中进行了描述。
动态 DNS 注册
在典型的 Active Directory 环境中,每台计算机都可以向 DNS 服务器注册自己的地址。当主机是多宿主时,它将注册其所有地址,甚至来自 6to4 隧道。
大多数互联网服务不使用动态 DNS,因此此问题通常仅限于客户端和服务器都在同一网络“内部”的企业站点。
客户端应用程序不会正常失败
Microsoft 的 RDP 客户端是不能优雅地处理 IPv6 路由问题的客户端应用程序的一个示例。大多数网络浏览器都更擅长处理像这样的 IPv6 边缘情况,因此它们不倾向于显示这种行为。
我意识到这对这种情况不是很有帮助,但是对于面临类似困境的实现者来说,有一种称为“Happy Eyeballs”(RFC 6555)的实现技术,它指定了一种同时连接到 ipv4 和 ipv6 并选择先连接的技术。
这是我的解决方案。默认情况下,Windows 赋予 IPv6 路由比 IPv4 路由更高的优先级。如果您编辑 IPv6 前缀策略,您可以更改此行为以使其优先使用 IPv4 而不是 IPv6。
为了确保我网络中的所有系统都以相同的方式设置,我将以下命令放入在构建或翻新机器后在软件安装期间运行的 .bat 脚本中。
要解释这是做什么的:
前 3 行禁用内置隧道接口,因为它们对于大多数网络都是冗余的。如果您没有为您的机器提供自己的 IPv6 地址,您可能不想使用这 3 行,在我的情况下,我有一个 DHCPv6 服务器和相关的基础设施,为隧道连接分配 IPv6
第二个命令块删除所有现有的 IPv6 路由前缀策略。
然后第三个块重新创建 IPv6 前缀策略,但使用一组不同的优先级。像这样,对应于 IPv4 的前缀优先于 IPv6,然后机器将希望使用 IPv4,除非应用程序指定使用 IPv6。
此解决方案保留了功能性双栈功能,但首选使用 IPv4 意味着 IPv6 不完整、不可靠或性能不佳的站点将避免使用它,除非系统上的程序要求这样做。
我认为让操作系统优先使用 IPv6 而不是 IPv4 实际上阻碍了采用。在过渡期间,有时主机认为它具有 IPv6 连接,但实际上并没有完整的功能连接,从而导致软件故障和大量延迟。我认识的许多人已经在他们的路由器上完全禁用了 IPv6,作为 ISP 在建立完全连接之前最初以损坏的方式部署 IPv6 的一种解决方法,这些人只会忘记再次启用它,让他们没有 IPv6,直到他们再次重新配置他们的路由器。