使用 mDNS reflector 解决 VLAN 隔离下 IoT 设备的服务发现问题

不少热衷于智能家居的朋友应该也和我一样为 IoT 设备启用了专用的 VLAN 和 SSID ,配合防火墙、QoS 甚至 DTIM 等高级设置能尽量确保这些设备被“关在笼子里”。如果你还没有这样做,这篇文章(对 Unifi 用户来说)可以是个简单可上手的参考。

然而这样一轮设置以后,你或许会发现无法使用 Airplay/DLNA/Miracast 等功能进行投屏了。问题出在 mDNS(Bonjour/Zeroconf) 协议被 VLAN 所隔离导致 AppleTV, HomePod, Google Nest/Chromecast 等设备的服务发现出了问题。网上有不少文章会解释原因并指导你如何解决,但每个人的家庭网络环境不尽相同,有时候解决方法并不是控制面板上一个选项那么简单。

比如我的网络拓扑大致是:ONT - RouterOS - PoE+ Switch - Unifi APs,“傻瓜”交换机和 RouterOS 默认没有提供 mDNS reflector/repeater 的能力。通过爬文可以找到诸如 Avahi 这样的软件能够解决问题,我则选择了 vfreex/mdns-reflector ,相比之下它更轻量,专注于解决这个单一问题,另外它还默认提供 arm 的 docker 镜像,正好可以长期跑在闲置的树莓派上。

下面简单介绍下我的配置方式:

假设默认网卡为 eth0,IoT VLAN id 为 10,另一个访客网络 VLAN id 为 20; 树莓派 2B 刷了 HypriotOS 系统,默认安装最新版 docker 。

# 确认内核加载 8021q 模块以支持 VLAN
modprobe 8021q
lsmod | grep 8021q

# 虚拟一个网卡, VLAN id 是 10
ip link add link eth0 name eth0.10 type vlan id 10
ip link set eth0.10 up
ip link show eth0.10

# 另一个网卡, VLAN id 是 20
ip link add link eth0 name eth0.20 type vlan id 20
ip link set eth0.20 up
ip link show eth0.20

# 通过 HDCP 自动获取 IP
dhclient eth0.10
ip addr show eth0.10
dhclient eth0.20
ip addr show eth0.20

# 以只读模式运行 mdns-reflector ,它会跨多个 VLAN 反射各设备的 mDNS 服务
docker run --read-only --restart=always --net=host --cap-add NET_RAW -d yuxzhu/mdns-reflector:latest mdns-reflector -fn eth0 eth0.10 eth0.20

跑起来后不会有 stdout 内容,你可以用 RouterOS Tools/Torch 抓 VLAN 上的 IGMP 流量,或直接打开手机搜索可投屏设备来验证。

P.S. RouterOS 用户还建议在 Bridge 上开启 IGMP Snooping,并尝试开启 Multicast Enhancement / IGMPv3

更早的文章

Bring back the beats

加入某创业公司近两年,这个 Blog 也差不多消失了相同的时间。最近刚好有闲可以整理一下生活,得益于 Hugo 和 Cloudflare Pages 的简单易用,很快就顺手恢复了它。 说是“恢复…

life 继续阅读