DNS Name Resolution in Windows with Multiple Network Interfaces

The problem of DNS name resolution on a system with multiple network interfaces

To resolve a hostname, a client computer queries a DNS server and receives an answer, e.g., an IP address. This logic is straightforward when there is only one network interface (a network connection, such as Ethernet, Wi-Fi, VPN, etc.) on the system. If there are multiple interfaces with multiple DNS servers, however, a number of questions and problems arise:

  1. Which DNS server and interface should the resolver use?
  2. Should the servers be queried simultaneously or one by one?
  3. What should be done if the answers from different DNS servers do not match?
  4. How does one determinate the priority and order of the DNS servers and the fallback logic?

Unfortunately, there is no universal answer to these questions. In each case, the resolution logic depends on the network configuration and scenario.

The problems become even more prominent if a VPN connection is involved.

  1. Some hostnames may be resolved only through the DNS server of the VPN connection.
  2. If a hostname from inside the VPN gets resolved through the public network, security and privacy are compromised. For example, a remote worker connects to the corporate LAN over a VPN. The Windows resolver can pass the hostnames from the corporate network to the untrusted public DNS servers over an unencrypted network connection. This may leak information about the corporate network to the outside.
  3. Resolutions intended for the public internet may get to the VPN. This may compromise privacy and generate an unwanted load on the DNS server inside the VPN. For example, a remote worker connects to the corporate LAN over a VPN. The Windows resolver may forward all the user's DNS requests to the VPN. Consequently, the list of the sites visited by the user will be visible to the administrator of the corporate DNS server.

How does Windows DNS resolver deal with multiple network interfaces?

Windows uses a very complex logic for name resolution when dealing with multiple network interfaces.

The behavior can be changed from multiple points:

  1. The network adapter priorities can be managed by a parameter called the interface metric, which can be changed for each adapter through Control Panel ( Adapter->Properties->TCP/IPv4(IPv6)->Properties->Advanced->Interface metric) or Power Shell commands ( Get-NetIPInterface and Set-NetIPInterface).
  2. From the Group Policy Editor (gpedit.msc) at Computer Configuration->Administrative Templates->Network->DNS Client.
  3. From the system registry (regedit.exe):
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters
    Some of the parameters are:
    -DynamicServerQueryOrder
    -DisableSmartNameResolution
    -DisableParallelAandAAAA

All of the above parameters are independent and may interfere with one another.

In our tests, Windows 10 with a default configuration and a VPN connection has sent DNS requests to all available DNS servers through all interfaces.

Below is a verbose log of the YogaDNS tool running in bypass mode.

[03.13 18:54:38] iana.org - request : type=A, server=103.86.96.100:53, program=svchost.exe
[03.13 18:54:38] iana.org - bypass : rule=Default
[03.13 18:54:38] iana.org - request : type=A, server=10.0.0.1:53, program=svchost.exe
[03.13 18:54:38] iana.org - bypass : rule=Default
[03.13 18:54:38] iana.org - reply (direct) : type=A, ips=192.0.43.8
[03.13 18:54:38] iana.org - reply (direct) : type=A, ips=192.0.43.8

It is clearly visible that the Windows system resolver (svchost.exe) tries to resolve the same hostname (iana.org) through two DNS servers (VPN 103.86.96.100 and Ethernet 10.0.0.1) at the same time. Both servers return the same answer. If the hostname belonged only to the LAN of the VPN, it would effectively mean that the name would be revealed to the public network. This condition is also known as DNS Leak.

Under some conditions or due to an incorrect configuration, Windows may stick to the DNS server of only a specific connection and ignore all other DNS servers. It may prevent the client from resolving hostnames that are serviced only by a specific DNS server (e.g., LAN internal names).

Another problem may arise when a single hostname resolves to different IP addresses inside and outside the LAN.

An easy way to manage resolution logic

All problems of DNS resolution through multiple network interfaces can be easily solved with YogaDNS, a small software tool with an easy yet powerful UI that can transparently intercept DNS queries from apps and system resolver and process them according to user-defined rules. With YogaDNS you can:

  • Create a set of rules for name resolution
    Create a set of rules for name resolution
  • Use specific DNS servers or an interface's default DNS servers
    Use specific DNS servers or an interface default DNS servers
  • Block or exclude (bypass) certain hostnames from processing
    Block or exclude (bypass) certain hostnames from processing
  • Properly manage scenarios when specific network interfaces are down
    Properly manage scenarios when specific network interfaces are down

Testing

For a test, we take a Windows 10 system with Ethernet and VPN connections. Assume that the VPN connects to a corporate LAN with domains such as *.corpdomain.
Below is an example of two resolutions: test.corpdomain and iana.org.

[03.19 16:15:07] test.corpdomain - request : type=A, id=9239, server=103.86.99.100:53, program=svchost.exe, pid=1272
[03.19 16:15:07] test.corpdomain - bypass : rule=Default
[03.19 16:15:07] test.corpdomain - request : type=A, id=50817, server=10.0.0.1:53, program=svchost.exe, pid=1272
[03.19 16:15:07] test.corpdomain - bypass : rule=Default
[03.19 16:15:07] test.corpdomain - reply (direct) : type=A, id=50817, ips=
[03.19 16:15:07] test.corpdomain - reply (direct) : type=A, id=9239, ips=192.172.1.7
[03.19 16:15:11] iana.org - request : type=A, id=36739, server=103.86.99.100:53, program=svchost.exe, pid=1272
[03.19 16:15:11] iana.org - bypass : rule=Default
[03.19 16:15:11] iana.org - request : type=A, id=18268, server=10.0.0.1:53, program=svchost.exe, pid=1272
[03.19 16:15:11] iana.org - bypass : rule=Default
[03.19 16:15:11] iana.org - reply (direct) : type=A, id=18268, ips=192.0.43.8
[03.19 16:15:11] iana.org - reply (direct) : type=A, id=36739, ips=192.0.43.8

It is clear that Windows tries to resolve all the names through both interfaces at the same time. Thus, queries for test.corpdomain and iana.org go to two DNS Servers: 103.86.99.100 (VPN) and 10.0.0.1 (Ethernet).
As described above in this article, this situation is suboptimal and may lead to security and performance problems.

To solve all these problems, you can simply create a single rule in YogaDNS, which will indicate that all the names that match *.corpdomain should be resolved through the VPN interface.

  1. To do this, please download, install, and run YogaDNS.
  2. Go to Configuration->Rules via the menu or the toolbar icon. Click the Add... button.
  3. Create a rule for *.corpdomain.
    Set Action to match your VPN connection.
    Set DNS Server to Default.
    Click OK.
    Rule for a VPN connection
  4. Set Action for the Default rule to Process via Ethernet0.
  5. The rule list should look like this:
    Rule list

That's it. Now, if we repeat the test again in the debug log, it is clear that Windows still tries to resolve using both interfaces and DNS servers, but YogaDNS forces the requests as specified by the rules.

[03.19 16:34:15] test.corpdomain - request : type=A, id=62391, server=103.86.96.100:53, program=svchost.exe, pid=1272
[03.19 16:34:15] test.corpdomain - process : server=103.86.96.100 (Plain, 103.86.96.100), interface=TestVPN (10.6.2.178), rule=MyCorp
[03.19 16:34:15] test.corpdomain - request : type=A, id=15697, server=10.0.0.1:53, program=svchost.exe, pid=1272
[03.19 16:34:15] test.corpdomain - process : server=103.86.96.100 (Plain, 103.86.96.100), interface=TestVPN (10.6.2.178), rule=MyCorp
[03.19 16:34:15] test.corpdomain - reply : type=A, id=9, ips=192.172.1.7
[03.19 16:34:15] test.corpdomain - reply : type=A, id=10, ips=192.172.1.7
[03.19 16:34:17] iana.org - request : type=A, id=28618, server=103.86.96.100:53, program=svchost.exe, pid=1272
[03.19 16:34:17] iana.org - process : server=10.0.0.1 (Plain, 10.0.0.1), interface=Ethernet0 (10.0.0.100), rule=Default
[03.19 16:34:17] iana.org - request : type=A, id=3671, server=10.0.0.1:53, program=svchost.exe, pid=1272
[03.19 16:34:17] iana.org - process : server=10.0.0.1 (Plain, 10.0.0.1), interface=Ethernet0 (10.0.0.100), rule=Default
[03.19 16:34:17] iana.org - reply : type=A, id=11, ips=192.0.43.8
[03.19 16:34:17] iana.org - reply : type=A, id=12, ips=192.0.43.8

Thus, test.corpdomain gets resolved only through the VPN connection (DNS server 103.86.96.100), and iana.org gets resolved only through the Ethernet connection (DNS server 10.0.0.1).

With YogaDNS, you can create much more complex rules, include hostnames from files, use the DNSCrypt and DNS over HTTPS protocols, and use DNSSEC.