Windows 在 DNS 查找中未返回任何 IPv6 地址

Windows 在 DNS 查找中未返回任何 IPv6 地址

我的 DNS 包含 ServerA 的两条记录:

  • 其 IPv4 地址为 10.25.46.130 的 A 记录
  • 带有 IPv6 地址的 AAAA 记录:fda8:6c3:ce53:a890::55

我无法得到我的简单客户端.java程序(来源在本文末尾)在 Windows 服务器上列出 IPv6 地址服务器A使用InetAddress.getAllByName(),即使在使用配置JVM时也是如此-Djava.net.preferIPv6Addresses=true

在启用 IPv6 的 Linux 服务器上运行相同的测试成功。

配置详细信息:

  • Windows:Server 2019 标准版 (10.0.17763)
  • Java:OpenJDK 11.0.5+

Windows 服务器上的输出ipconfig显示 IPv6 似乎已启用:

> ipconfig
Windows IP Configuration

Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   IPv4 Address. . . . . . . . . . . : 10.25.0.214
   Subnet Mask . . . . . . . . . . . : X.X.X.X
   Default Gateway . . . . . . . . . : X.X.X.X

Ethernet adapter Ethernet 2:

   Connection-specific DNS Suffix  . : fr.company.com
   IPv6 Address. . . . . . . . . . . : fda8:6c3:ce53:a890::3
   Link-local IPv6 Address . . . . . : X.X.X.X::X
   Default Gateway . . . . . . . . . : X.X.X.X::X

nslookupWindows 服务器的输出是预期的输出:

> nslookup ServerA
Server:  dns.fr.company.com
Address:  X.X.X.X

Non-authoritative answer:
Name:    ServerA.fr.company.com
Addresses:  fda8:6c3:ce53:a890::55
          10.25.46.130

我能够ping -6 ServerA从 Windows 服务器成功运行:

> ping -6 ServerA
Pinging ServerA.fr.company.com [fda8:6c3:ce53:a890::55] with 32 bytes of data:
Reply from fda8:6c3:ce53:a890::55: time<1ms
Reply from fda8:6c3:ce53:a890::55: time<1ms

以下是预期输出从启用 IPv6 的 Linux 服务器运行:

# IPv4 (default)
$ java SimpleClient.java ServerA 12345
preferIPv6Addresses: null
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130
ServerA/fda8:6c3:ce53:a890:0:0:0:55

# IPv6
$ java -Djava.net.preferIPv6Addresses=true SimpleClient.java ServerA 12345
preferIPv6Addresses: true
InetAddress.getByName()
ServerA/fda8:6c3:ce53:a890:0:0:0:55
InetAddress.getAllByName()
ServerA/fda8:6c3:ce53:a890:0:0:0:55
ServerA/10.25.46.130

相同的测试在 Windows 服务器上失败:

# IPv4 (default)
> java SimpleClient.java ServerA 12345
preferIPv6Addresses: null
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

# IPv6
> java -Djava.net.preferIPv6Addresses=true SimpleClient.java ServerA 12345
preferIPv6Addresses: true
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

在 Windows 服务器上,对的调用InetAddress.getAllByName()仅返回单个 IPv4 地址,而不是像在启用了 Linux IPv6 的服务器上预期的那样同时返回 IPv4 和 IPv6 地址。

我可以在禁用 IPv6(grub 和内核设置)的 Linux 服务器上重现相同的行为:

# IPv4 (default)
$ java SimpleClient.java ServerA 12345
preferIPv6Addresses: null
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

# IPv6
$ java -Djava.net.preferIPv6Addresses=true SimpleClient.java ServerA 12345
preferIPv6Addresses: true
InetAddress.getByName()
ServerA/10.25.46.130
InetAddress.getAllByName()
ServerA/10.25.46.130

通过这些测试,我得出结论,Windows 服务器的 IPv6 配置某处有问题,但我不知道是什么问题。

我尝试过的一些笔记和东西:

  • 手动添加 IPv6 地址服务器AC:\Windows\System32\drivers\etc\hosts导致程序列出 IPv6 地址,但仅此一个。
  • 我没有DisabledComponents在注册表中找到该路径的键Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters

以下是代码示例客户端.java

import java.net.Socket;
import java.net.UnknownHostException;
import java.net.InetAddress;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.IOException;

public class SimpleClient {
    public static void main(String[] args) {
        if (args.length < 2) return;
        String hostname = args[0];
        System.out.println("preferIPv6Addresses: " + System.getProperty("java.net.preferIPv6Addresses"));
        try {
          System.out.println("InetAddress.getByName()");
          System.out.println(InetAddress.getByName(hostname));
          InetAddress[] addresses = InetAddress.getAllByName(hostname);
          System.out.println("InetAddress.getAllByName()");
          for (InetAddress address : addresses) {
            System.out.println(address);
          }
        } catch (UnknownHostException ex) {
            System.out.println("Server not found: " + ex.getMessage());
        }
        int port = Integer.parseInt(args[1]);
        try (Socket socket = new Socket(hostname, port)) {
            InputStream input = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            System.out.println(reader.readLine());
        } catch (UnknownHostException ex) {
            System.out.println("Server not found: " + ex.getMessage());
        } catch (IOException ex) {
            System.out.println("I/O error: " + ex.getMessage());
        }
    }
}

有人可以提示一下 Windows 服务器配置可能出了什么问题吗?

谢谢。

编辑1:

正如评论中提到的,我也使用 Python 重现了这个问题socket.getaddrinfo()

  • Windows 服务器(无AF_INET6
>>> socket.getaddrinfo("serverA", 12345)
[(<AddressFamily.AF_INET: 2>, 0, 0, '', ('10.25.46.130', 12345))]
  • Linux 服务器(两者皆AF_INET6AF_INET
>>> socket.getaddrinfo("serverA", 12345)
[(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('10.25.46.130', 12345)),
 (<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_DGRAM: 2>, 17, '', ('10.25.46.130', 12345)),
 (<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_RAW: 3>, 0, '', ('10.25.46.130', 12345)),
 (<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('fda8:6c3:ce53:a890::55', 12345, 0, 0)),
 (<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_DGRAM: 2>, 17, '', ('fda8:6c3:ce53:a890::55', 12345, 0, 0)),
 (<AddressFamily.AF_INET6: 10>, <SocketKind.SOCK_RAW: 3>, 0, '', ('fda8:6c3:ce53:a890::55', 12345, 0, 0))]

答案1

答案来自评论中的@user1686,指出IPv4和IPv6在不同的接口上是分开的。

看来我们的 IT 部门为 Windows 服务器配备了两个接口,每个 IP 堆栈专用一个:

  • 以太网(IPv4)
  • 以太网4(IPv6)

我禁用了 Windows 服务器上的所有额外接口,只保留了“以太网“ 一:

在网络管理器中禁用接口

我在“以太网” 通过复制粘贴“以太网 4”:

在仅支持 IPv6 的接口上启用 IPv6

所结果的ipconfig显示同时具有 IPv4 和 IPv6 的单个接口:

> ipconfig

Windows IP Configuration

Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . :
   IPv6 Address. . . . . . . . . . . : fda8:6c3:ce53:a890::3
   Link-local IPv6 Address . . . . . : fe80::8d10:5083:9a0:9ab8%16
   IPv4 Address. . . . . . . . . . . : 10.25.0.214
   Subnet Mask . . . . . . . . . . . : Z.Z.Z.Z
   Default Gateway . . . . . . . . . : Y:Y:Y:Y::T
                                       X.X.X.X

重新配置后,测试运行正常,并列出了服务器 A 的 IPv4 和 IPv6 地址:

# IPv4
> C:\jdk11.0.8\bin\java SimpleClient.java serverA 12345
preferIPv6Addresses: null
InetAddress.getByName()
serverA/10.25.46.130
InetAddress.getAllByName()
serverA/10.25.46.130
serverA/fda8:6c3:ce53:a890:0:0:0:55

# IPv6
> C:\jdk11.0.8\bin\java -Djava.net.preferIPv6Addresses=true SimpleClient.java serverA 12345
preferIPv6Addresses: true
InetAddress.getByName()
serverA/fda8:6c3:ce53:a890:0:0:0:55
InetAddress.getAllByName()
serverA/fda8:6c3:ce53:a890:0:0:0:55
serverA/10.25.46.130

因此,尝试在不同的接口上隔离 IP 堆栈似乎是不是一个好主意。

相关内容