将 mDNS 查询从 WSL 子网重新路由到 Windows 主机子网

Sis*_*phe 6 routes mdns subnet dns-sd windows-subsystem-for-linux

Heya 编码员/开发人员/网络人员/Devops/...

我在 WSL2(Windows 10 2004 版本)上下文中遇到mDNS/DNS-SD设置问题

我在家里有一个非常简单的设置,有一个主服务器和一个 Raspberry Pi,我想激活 DNS 服务发现,从而让我有一种简单的方法在我的 Raspberry PI 上自动发现我的服务器。

使用像dnssd这样的简单库,甚至自己广播正确的数据,我设法在不使用 WSL2 时使其轻松工作。但是我有一个要求让它在 WSL2 上工作,这就是事情变得复杂的地方。

由于 WSL2 在其自己的子网上运行,因此广播不再起作用。在子网上使用 mDNS 仅适用于该子网。然而,Windows 已经重新路由了主机和 WSL 之间的一些广播流量。

这很容易测试:Ping从我的服务器到依赖 mDNS 的 Pi 的 Avahi 地址做一个简单的工作。

在此处输入图片说明

在屏幕左侧,您可以看到 Wireshark 在主机网络接口上捕获的流量,在右侧,您可以看到 Wireshark 在 WSL 网络接口上捕获的流量。前3行是一个简单的ping:它是在WSL的上下文中执行的,但是这里出现的IP地址172.28.192.1——不是WSL客户端的IP地址,而是WSL内部DNS服务器的IP地址。正如您在右侧看到的那样,它在主机上完美地重新路由,带有 Windows 主机的 IP 地址:192.168.0.39

但是,由脚本执行的第二个查询具有 WSL 源 IP ( 172.28.204.42),并且该查询不会在主机上重新路由。

我的网络知识非常有限,我不明白这是如何工作的,以及如何让 WSL 在主机上路由我自己的 mDNS 查询。一个疯狂的猜测是它与 iptables 有关,但就我而言。

如果有人知道为什么它适用于 DNS 服务器源地址而不是当我自己执行它时,这将对我有很大帮助!

编辑 1:WSL 路由表 在此处输入图片说明

hru*_*ing 4

WSL2 Hyper-V 网络交换机不充当多播网桥。默认情况下,交换机创建内部网络。多播数据包仅传送到连接到内部网络的系统,而不传送到内部网络之外的任何系统。有关 Hyper-V 网络类型的更多信息,请参阅这篇 Nakivo 博客文章

在第一种情况下,ping 会触发前往解析器(Windows 主机)的常规 DNS 查找。然后,Windows 主机在其外部和内部网络上执行 mDNS 查找。您的数据包转储显示了内部查找,但请注意,没有任何响应。响应来自外部网络,并且 ping 通过常规 DNS 获取响应。在第二种情况下,您仅执行 mDNS 查找。该查找没有收到任何响应,因为它只发送到内部网络。为了证明 mDNS 查找在内部网络上有效,请查找 Windows 主机的本地地址 (MACHINE.local)。它会起作用,因为 Windows 主机位于内部网络上并且可以响应。

好消息是您可以更改 WSL 网络类型。

  1. 按 Windows 键并输入“Hyper-V Manager”
  2. 右键单击该应用程序并选择“以管理员身份运行”
  3. 在管理器中,在“Hyper-V Manager”下找到您的计算机,然后单击它
  4. 在操作区域中,单击“虚拟交换机管理器...”
  5. 找到 WSL 开关并单击它
  6. 将连接类型更改为“外部网络”
  7. 单击“确定”

Hyper-V 管理器屏幕截图

执行此操作后,重新启动 WSL:

> wsl --shutdown
> wsl -t <distribution-name>
> wsl --distribution <distribution-name>
Run Code Online (Sandbox Code Playgroud)

一旦重新启动,您的访客的网络就会中断。您需要使用ip addr addip route或类似的方法从外部网络添加 IP 地址和路由。您的发行版几乎肯定会在每次启动时尝试为默认 WSL 交换机设置其网络,因此您可能需要设置配置以在将来添加此外部网络地址。例如,无论交换机配置如何,Ubuntu 20.04 始终在内部网络上添加动态地址。

出于同样的原因,更改网络交换机类型可能会破坏 WSL2 的其他用途(例如 Docker Desktop)。Windows 每次重新启动时都会重新创建 Hyper-V 网络交换机,因此您的更改只会在系统保持运行状态时持续。