Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reroute mDNS query from WSL subnet to windows host subnet

Heya fellow coders/developers/networkers/Devops/...

I have an issue with an mDNS/DNS-SD setup in the context of WSL2 (Windows 10 2004 version)

I have a pretty simple setup at home with a main server and a Raspberry Pi, and I would like to activate DNS service discovery, thus allowing me to have a simple way to do automatic discovery of my server on my Raspberry PI.

Using a simple library like dnssd, or even broadcasting the right data myself, I manage to make it work easily when not using WSL2. However I have a requirement to make it work on WSL2 and this is where things get complicated.

As WSL2 is running on its own subnet, the broadcasting does not work anymore. Using mDNS on a subnet only works in this subnet. However Windows already reroute some of the broadcast traffic between the host and WSL.

This is testable easily : doing a simple Ping from my server to the Avahi address of the Pi which relies on mDNS works.

enter image description here

On the left side of the screen you can see traffic captured by Wireshark on the host network interface and on the right side, you can see the traffic captured by Wireshark on the WSL network interface. The first 3 lines are a simple ping : it is executed in the context of WSL, but the IP address that appears here - 172.28.192.1- is not the IP address of the WSL client, it is the IP address of the internal DNS server of WSL. It is perfectly rerouted on the host as you can see on the right, with the IP address of the windows host: 192.168.0.39

However, the second query, which is executed by a script, has the WSL source IP (172.28.204.42) and this one is not rerouted on the host.

My network knowledge is very limited and I do not understand how this work, and how I could make WSL route my own mDNS queries on the host. A wild guess would be that it has something to do with iptables, but that is as far as I go.

If anyone has a clue on why it works on the DNS server source address and not when I perform it myself it would help me a lot !

Edit 1 : WSL Route table enter image description here

like image 325
Sisyphe Avatar asked May 30 '20 20:05

Sisyphe


1 Answers

The WSL2 Hyper-V network switch does not act as a multicast bridge. By default, the switch creates an internal network. Multicast packets are only delivered to systems connected to the internal network and not to anything beyond it. More information about Hyper-V network types can be found in this Nakivo blog post.

In your first case, the ping triggers a regular DNS lookup that goes to the resolver -- the Windows host. The Windows host then performs an mDNS lookup on both its external and internal networks. Your packet dump shows the internal lookup, but note that nothing responds to it. The response comes via the external network, and the ping gets its response via regular DNS. In your second case, you perform only an mDNS lookup. That lookup receives no response, because it only goes to the internal network. For proof that mDNS lookups work on the internal network, do a lookup for the Windows host's local address (MACHINE.local). It will work, because the Windows host is on the internal network and can respond.

The good news is you can change the WSL network type.

  1. Hit your Windows key and type "Hyper-V Manager"
  2. Right-click on the app and choose "Run as administrator"
  3. In the manager, find your machine under "Hyper-V Manager" and click on it
  4. In the Actions area, click on "Virtual Switch Manager..."
  5. Find the WSL switch and click on it
  6. Change the connection type to "External network"
  7. Click OK

Hyper-V Manager Screenshot

After doing this, restart WSL:

> wsl --shutdown
> wsl -t <distribution-name>
> wsl --distribution <distribution-name>

Once restarted, your guest's network will be broken. You will need to add an IP address and route from your external network using ip addr add and ip route or something similar. Your distribution is almost certainly going to try to setup its network for the default WSL switch every time it starts, so you may need to setup configurations to add this external network address in the future. As an example, Ubuntu 20.04 always adds a dynamic address on the internal network, regardless of the switch configuration.

Making the change to the network switch type will likely break other uses of WSL2 (e.g. Docker Desktop) for the same reason. Windows re-creates the Hyper-V network switch every time it reboots, so your change will only last as long as your system stays up.

like image 175
hrunting Avatar answered Sep 30 '22 14:09

hrunting