什么是mDNS(多播DNS)? .local地址与自动发现设备的原理

打印机、智能电视之所以能仅凭名字就自动找到彼此,而不需要任何DNS服务器,原理都在这里。

什么是mDNS(多播DNS)

通常要把域名解析成IP地址,需要向互联网上某台DNS服务器发起查询,但家里或办公室里的打印机、智能电视、音箱这类设备很难专门配置一台DNS服务器。mDNS让这些局域网内的设备通过多播方式广播“我的名字是这个”,其他设备需要时用同样的方式发起查询并获得响应,从而在完全没有DNS服务器的情况下也能完成名称解析。

.local域名

通过mDNS查找到的设备使用“.local”这个特殊的顶级域名,以便与普通域名区分开来。当打印机以类似“MyPrinter.local”的名字广播自己时,同一网络中的其他设备会自动识别出这个名字应该通过mDNS而不是普通DNS来解析。.local域名被专门保留、不会被路由到局域网之外,因此不会与真正的互联网域名体系产生冲突。

工作原理:多播查询与响应

mDNS使用UDP 5353端口,以及IPv4多播地址224.0.0.251(IPv6下为ff02::fb)。同一网络中所有支持mDNS的设备都在监听这个多播组,当收到与自己相关的名称查询时就用自己的IP地址响应。发起查询的设备会把这个响应缓存下来重复使用,并按需定期重新确认。

名称冲突:启动时先探测再占用

由于没有中心服务器来分配名字,两台设备可能想用同一个名称。mDNS规定设备在启用某个名称之前,要先在网络上发出几次探测查询,确认没有别人在用。如果发现冲突,设备必须换一个名字,常见做法是在名称末尾加上数字,例如从MyPrinter.local变成MyPrinter-2.local。因此你有时会发现设备的主机名莫名多了个“-2”,这通常说明网络里曾经出现过同名设备。

DNS-SD:发现服务本身的功能

与mDNS搭配使用的DNS-SD(DNS服务发现)不仅能回答“这个名字的设备在哪里”,还能回答“网络中有没有提供某种服务的设备”。比如用类似“_ipp._tcp.local”这样表示服务类型的名称发起查询,网络中所有打印机都会响应,并各自报告自己的名字、端口和相关信息。正因如此,用户即使不知道打印机的确切名称或IP地址,应用程序或操作系统也能自动列出“当前可用的打印机列表”。

实际应用场景

AirPlay、屏幕镜像、无线打印机自动发现、智能家居设备初始配置等,几乎所有“自动发现设备”的功能背后都有mDNS在起作用。iPhone能自动发现附近的Apple TV并显示在AirPlay列表中,网络打印机无需安装驱动就能直接出现在列表里,智能家居App能自动发现新接入的设备,靠的都是mDNS与DNS-SD的组合。苹果的实现名为Bonjour,Linux阵营则广泛使用Avahi。

代表性实现:Bonjour、Avahi、Zeroconf

实际实现mDNS/DNS-SD标准的软件统称为Zeroconf(零配置),这个名字来自“无需任何配置就能实现网络功能”这一目标。苹果将这一概念以Bonjour之名内置到了macOS和iOS系统中;在开源阵营,Avahi在Linux发行版中扮演着相同的角色。在Windows上,安装iTunes或部分打印机驱动时,往往也会一并安装并运行Bonjour服务。

跨网段、VLAN与访客Wi-Fi的限制

mDNS的数据包只在本地链路内传播,不会被路由器转发。因此,当手机在一个网段、智能电视在另一个网段(例如家里划分了独立的IoT网络或访客网络)时,手机就看不到电视。解决办法是在路由器或网关上启用mDNS中继(也叫反射器或代理),让它把多播查询在不同网段之间转发,或者干脆把需要互相发现的设备放在同一网段。启用时要注意,这样做也会让原本隔离的网段之间多出一条可被发现的通道。

安全与注意事项

mDNS的设计不需要任何认证、任何设备都可以响应,这意味着只要处于同一网络中,不可信的设备也可能伪造名称信息进行响应。在咖啡厅、机场这类公共Wi-Fi环境中,陌生人可能与你处于同一网络,需要留意mDNS可能让自己设备的名称或服务信息暴露给周围的人。另外,mDNS原本就被设计为只在局域网内工作,不会被路由到路由器之外的其他网段,这是正常现象;如果确实需要跨网段使用,则需要额外配置mDNS中继器。

不妨也了解一下普通DNS的完整流程

如果想知道互联网上普通域名解析成IP地址的完整过程,可以参考DNS查询过程完全解析一文。

与智能家居协议的关系

Zigbee、Z-Wave等智能家居设备使用的其他无线协议,可以参考智能家居网络协议完全解析一文进一步了解。

一次完整的发现过程

以手机寻找无线打印机为例:手机向多播地址发出一条查询,询问“谁提供打印服务”。局域网内的打印机收到后,返回自己的服务名称、端口以及主机名,同时附带它的IP地址。手机把结果显示在打印机列表中,并缓存一段时间,下次就不必重新查询。如果打印机关机,它通常会发出一条“告别”消息,让别的设备尽快把它从列表中移除。整个过程不需要手动输入IP地址,也不依赖任何中心服务器。

排查mDNS故障的思路

如果设备在列表里找不到,可以按以下顺序检查:首先确认两台设备在同一个网段、连接的是同一个Wi-Fi;其次检查路由器是否开启了AP隔离(客户端隔离)或限制多播,这两项是最常见的原因;再次查看电脑或设备上的防火墙是否放行了UDP 5353端口;最后可以尝试重启设备上的mDNS服务,例如Windows上的Bonjour服务或Linux上的avahi-daemon。许多路由器还有“IGMP侦听”之类的多播优化选项,配置不当也可能让mDNS时断时续。

与普通DNS并存

mDNS并不是用来取代DNS的。访问互联网上的网站依然靠普通DNS,mDNS只负责局域网内以.local结尾的名字。操作系统会根据名称后缀自动选择走哪条路径。需要注意的是,如果企业内部网络把.local用作内部域名,可能会和mDNS发生冲突,这也是现在不推荐用.local命名内网域名的原因。

常见问题

mDNS无法正常工作会怎样?

设备将无法再按名称自动被发现,可能需要在App或设置界面里手动输入IP地址来添加打印机或智能电视。路由器的多播相关设置,或者AP隔离(客户端隔离)功能,经常是阻断mDNS流量的原因,值得优先排查。

mDNS在没有互联网连接的情况下也能用吗?

可以。mDNS只在同一个局域网内工作,即使断开了互联网连接,只要设备连接在同一个Wi-Fi或路由器下,彼此依然能够互相发现。

mDNS和Bonjour是什么关系?

mDNS是一项公开的标准,Bonjour是苹果对mDNS和DNS-SD等零配置技术的实现和品牌名称。Linux上的Avahi等软件实现的是同样的标准,因此不同品牌的设备通常可以互相发现。

为什么我的手机找不到另一个网段里的设备?

因为mDNS的多播包不会被路由器转发到其他网段。需要把设备放在同一网段,或者在路由器上启用mDNS中继功能。

mDNS会不会泄露我的信息?

它会向同一网络中的所有设备公布设备名称和提供的服务,所以在公共Wi-Fi上,别人可能看到你的设备名称。建议不要把真实姓名放在设备名里,在不信任的网络上也可以关闭相关共享功能。