引子
不少热衷于智能家居的朋友应该也和我一样为 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 镜像,正好可以长期跑在闲置的树莓派上。
解决
下面简单介绍下我的配置方式:
树莓派刷了
HypriotOS
系统,默认安装最新版 docker 。 假设默认网卡为eth0
,IoT VLAN ID 为10
,另一个访客网络 VLAN ID 为20
。
# 确认内核加载 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
。