相较二进制地址,使用名称系统带来的效率提升显著。在局域网环境中,DNS 服务缺失的情况下,如何让应用程序继续使用名称解析的服务,产生了各种解决方案,其中的典型代表是 mDNS 和 LLMNR。
mDNS
设计缘起
传统的名称解析体系中,想访问一个设备(如一台打印机 printer.local),电脑需要去询问一个指定的 DNS 服务器(如路由器的 192.168.1.1 或公网的 8.8.8.8)。但是,在简单的家庭或办公室局域网中,可能并没有一个 DNS 服务器专门记录着所有设备的名称及地址。手动为每台设备配置 IP 地址或维护一个 DNS 列表也非常麻烦。
这种情况下如何实现电脑/设备间的相互发现与访问,mDNS 就是为了解决这个问题而生的。
mDNS,全名 Multicast DNS,中文译为“多播 DNS” 或“组播 DNS”,旨在没有传统 DNS 服务器的小型网络中(如家庭 Wi-Fi),将主机名解析为 IP 地址,可以把它们理解为一种“DNS 的局域网版本”。mDNS 是一种零配置网络协议(Zeroconf),它通过广播的方式相互发现并解析主机名,进而实现设备间的自动发现与通信 。
设计原理 — 广播与应答
mDNS 的工作方式非常直接,就像是在一个房间里大喊一声来问问题:
- 询问:当电脑需要解析 myprinter.local 这个地址时,它不会去问某个特定的名称服务器,而是会向整个本地网络广播一个问题:“喂!谁是 myprinter.local?你的IP地址是多少?” 这个广播会发送到一个特殊的组播地址 224.0.0.251(IPv4)或 ff02::fb(IPv6),局域网内的所有设备都能“听”到。
- 应答:网络上那台名叫 myprinter 的设备“听”到了这个询问,它会认出这是在叫自己。于是,它就会直接回复:“嗨,我就是 myprinter.local,我的 IP 地址是 192.168.1.105。”
- 完成解析:电脑收到回复后,知道了目标 IP,然后就可以正常建立连接了。
这个过程完全对等,不需要任何中心服务器。
核心特点
- 零配置:mDNS 是 Zeroconf 网络技术栈的核心部分之一。顾名思义,它的目标就是让设备接入网络后无需任何手动配置就能互相发现和使用。打印机、智能音箱、NAS、手机、电脑等设备接入同一网络后,就能自动被发现。
- 域名后缀 .local:mDNS 使用专用的顶级域名 .local。这是约定俗成的规则,用来明确区分于需要通过互联网 DNS 系统解析的域名(如 .com, .org)。所以,看到的 mDNS 主机名通常是 MyComputer.local、AirPrint-Printer.local 等。
- 基于 UDP:mDNS 使用 UDP 端口 5353。
mDNS 在各平台的实现
- Apple 平台 – Bonjour:苹果公司对 Zeroconf 技术的实现,广泛应用于 macOS、iOS 以及 AirPrint 打印机、AirPlay 音箱等设备。当用 Mac 查找共享的打印机或屏幕时,背后就是 Bonjour(mDNS)在起作用。
- Linux 平台 – Avahi:Linux 世界最流行的 Zeroconf/mDNS 实现。许多桌面发行版(如 Ubuntu, Fedora)都预装了 Avahi 守护进程(avahi-daemon),这样 Linux 电脑也能和苹果设备、打印机无缝协作。systemd-resolved 也内置了 mDNS 客户端功能。
- Windows 10/11 平台:从 Windows 10 开始,微软也原生支持了 mDNS,使得 Windows 设备能更好地融入智能家居和办公网络。
- 物联网设备:很多智能家居设备(如智能灯泡、插座)都使用 mDNS 来宣告自己的服务,方便手机 App 发现它们。
在 Linux 使用 mDNS
option 1. 使用 avahi 工具包
# 安装 avahi 工具
sudo apt install avahi-utils # Debian/Ubuntu
# 发现所有可用的 mDNS 服务
avahi-browse -a
# 解析一个特定的 .local 主机名
avahi-resolve-host-name myprinter.local
option 2. systemd-resolved
systemd-resolved 使用 mDNS 来解析 .local 域名。用 resolvectl 查看状态。
LLMNR
设计缘起
在公司的局域网里,想通过主机名快速访问同事的共享文件夹,比如 \\file-server。电脑会首先尝试向 DNS 服务器查询 file-server 的IP地址。但可能会遇到问题:
- 局域网里可能没有内建的 DNS 服务器来记录所有电脑的主机名;
- DNS 服务器可能因为故障而无法访问;
- file-server 这个名称可能并未注册到 DNS 服务器中;
在这种情况下,传统 DNS 解析会失败。LLMNR 就是作为 DNS 协议的一个后备方案被设计出来的,专门用于解决同一子网内主机之间的名称解析。
LLMNR,全名 Link-Local Multicast Name Resolution,中文译为“链路本地多播名称解析”,当传统的 DNS 服务器不可用或无法解析一个主机名时,它允许设备在本地网络中通过组播的方式直接询问其他设备:“你是不是叫这个名字?” 。
设计原理 — 基于组播的“喊话”机制
LLMNR 的工作方式与 mDNS 非常相似,也是基于“喊话”:
- 查询:当主机 A 想解析 host-b 这个名称,并且 DNS 查询失败后,它会转向使用 LLMNR。它向整个本地网络的所有主机组播一个查询包,询问:“谁是 host-b?” 这个包发送到特定的 IPv4 组播地址 224.0.0.252 或 IPv6 地址 ff02::1:3。
- 应答:网络上所有启用了 LLMNR 的主机都会收到这个查询。名叫 host-b 的那台主机 B 识别出这是自己的名字,就会直接向主机 A 单播一个响应,告知自己的 IP 地址。
- 完成解析:主机 A 收到响应后,就获得了主机 B 的 IP 地址,随后可建立连接(如SMB文件共享、远程桌面等)。
核心特点
- 零配置:和 mDNS 一样,LLMNR 也是零配置。
- DNS 的替补队员:LLMNR 只在传统 DNS 解析失败后才会被触发。它的设计目的是“尽力而为”地提供一种解析机制。
- 解析单标签名:LLMNR 主要用于解析单标签名称,即没有域名后缀的主机名(如 printserver)。它也可以用于解析完全合格域名,但这不是主要用途。
- Windows 原生支持:LLMNR 是由微软主导开发的,从 Windows Vista 开始成为默认启用的功能。
- 基于标准 DNS 格式:LLMNR 数据包使用标准的 DNS 数据包格式,简化了实现。
- 基于 UDP 和 TCP:使用 UDP 和 TCP 的 5355 端口。
LLMNR 应用场景 – Windows 原生
LLMNR 在基于 Windows 的局域网中无处不在:
- Windows 文件共享:当在“运行”框或文件管理器地址栏输入
\\computer-name访问另一台 Windows 电脑时,如果 DNS 失效,LLMNR 就会接手并帮忙找到对方。 - Windows 远程桌面:使用计算机名进行远程桌面连接时也会用到 LLMNR。
- 混合网络:在同时有 Windows 和 Linux 设备的网络中,如 Linux 系统也启用了 LLMNR(如通过 systemd-resolved 或 nss-mdns 包),也能被 Windows 电脑发现和访问。
mDNS vs. LLMNR
LLMNR 和 mDNS 功能相似,但来自不同的阵营,有一些关键区别,
| 属性 | LLMNR(链路本地多播名称解析) | mDNS(多播 DNS) |
|---|---|---|
| 发起方 | 微软 | 苹果(作为Bonjour/Zeroconf的一部分) |
| 解析目标 | 解析单标签主机名(如 HOSTNAME),作为DNS的后备 | 零配置服务发现,使用 .local 域名 |
| 协议/端口 | UDP/TCP 5355 | UDP 5353 |
| 广播地址 | IPv4: 224.0.0.252, IPv6: ff02::1:3 | IPv4: 224.0.0.251, IPv6: ff02::fb |
| 主要生态系统 | Windows 网络(Vista及之后版本原生支持) | Apple生态(macOS, iOS, AirPlay, AirPrint), Linux(Avahi) |
| 设计哲学 | 解决DNS失效时的主机名解析 | 构建一个完整的、无需服务器的本地服务发现体系 |
安全风险
LLMNR 和 mDNS 有一个共同的知名安全风险:它们信任本地网络上的任何响应。
攻击者如果也在局域网内,可以轻松地进行“中毒”攻击,伪装成你正在寻找的设备,所以当有客户尝试解析域名的时候,恶意节点可以返回错误信息,以至于客户端认为恶意节点的 IP 就是域名对应的 IP (或者解析出不存在的 IP),从而将流量劫持到恶意服务器上(用于窃取密码哈希,即著名的“应答攻击”)。
在企业安全要求高的环境中,往往会禁用 LLMNR 和 mDNS。
禁用局域网域名解析广播
禁用 LLMNR
- Windows 平台
打开本地组策略编辑器(gpedit.msc),
计算机配置->管理模板->网络->DNS 客户端->关闭多播名称解析
或
打开注册表,设置
HKLM\Software\Policies\Microsoft\Windows NT\DNSClient\EnableMulticast为 0
- Linux 平台
在 /etc/systemd/resolved.conf 中,添加
LLMNR=no
Reference
- https://www.reddit.com/r/sysadmin/comments/sbktqr/security_cadence_disable_llmnr/?tl=zh-hans
- 在 Windows 和 Linux 系统上禁用 LLMNR 以及 NetBIOS