multicast DNS

背景

我之前一直都在想,怎么解决路由器的DNS的映射问题。其实要求不高,只需要一个符合逻辑的 域名 就可以了。

太难了,不管是之前的小米路由器,还是现在的华硕路由器,维护起来太麻烦。

所以现在我要介绍一个技术:mDNS

路由器 DNS

一般来说路由器上都会自带一个DNS作为缓存(dnsmasq),用来加速访问。

不管是运营商提供的 DNS 或者是 Public DNS,延迟 一般都会在 5 - 30 ms 左右,而路由器上的 DNS 因为距离实在太短了,所以 几乎都在 <= 1 m, 所以一般情况下 会有 5 - 30倍的速度提升。

Also,你还可以利用这个本地DNS来做一些自定义功能,比如做一些短域名解析,或者说自定义的主机解析。但大多数路由器厂商都没有提供这个功能。

这也是我感到非常烦的地方。

mDNS

忽然有一天 我发现 通过 主机名也可以找到地址。但是 使用 nslookup 却从路由器上找不到这个映射。但是 ping, curl 这类工具是完全可以访问的。

但也好像不是所有软件都能正常识别这个域名,例如 Firefox 就不支持 hostname. 来去访问。

好奇怪。

再进一步 发现了个 hostname.local 这么个域名,

这样 所有的软件 都能够正常工作了。

但原理是什么?

搜索了一下 在 Wikipedia 发现了 这么个解释

.local已被指定用于链路本地网络,多播DNS(mDNS)[2]和零配置网络(zeroconf)的应用,因此可以在没有在局域网上本地安装传统DNS基础设施的情况下建立DNS服务。

所以 mDNS 是完全不依靠 DNS(53) 服务的。

那这样看来 就需要每个节点来去自治了, 很有“去中心化”的那种感觉。很不错 我喜欢。

platform

接下来就看支持的平台了。

看了下。

RFC 6762由Apple Inc.员工Stuart Cheshire和Marc Krochmal撰写,Apple的Bonjour zeroconf网络软件实现了mDNS。[3]如果将 .local 附加到主机名中,则该服务将自动解析运行 MacOS 的链路本地 Macintosh 计算机和运行 iOS 的移动设备的专用 IP 地址。此外,Bonjour 设备在向 DNS 服务发现客户端播发服务时,将使用这些 .local 主机名。

原来是 Apple 做的东西,再一次 感觉 Apple 软件工程师 都是TMD的天才。

这样 Apple 系列的都是可以支持的,剩下的就看 Windows 和 Linux了。

Windows 从 1803 开始支持 mDNS,新版本的都可以 “ZERO CONFIG” 了。

但是 Linux 这边不是很好,大多数发行版都不会默认安装 mDNS

Ubuntu

ubuntu 软件生态会比较丰富,只需要安装 avahi 的服务即可。

apt install avahi

# or ubuntu 22 
apt install avahi-discover

通过 service avahi-daemon status 来查看服务状态。

Alpine

Alpine 作为 一个近年活跃的 Linux 发行版,软件生态还欠缺了点。

比如 直接安装 avahi 就会报错

May 19 00:45:12 alpine daemon.info avahi-daemon[9321]: Found user 'avahi' (UID 86) and group 'avahi' (GID 86).
May 19 00:45:12 alpine daemon.info avahi-daemon[9321]: Successfully dropped root privileges.
May 19 00:45:12 alpine daemon.info avahi-daemon[9321]: avahi-daemon 0.8 starting up.
May 19 00:45:12 alpine daemon.warn avahi-daemon[9321]: WARNING: No NSS support for mDNS detected, consider installing nss-mdns!
May 19 00:45:12 alpine daemon.err avahi-daemon[9321]: dbus_bus_get_private(): Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
May 19 00:45:12 alpine daemon.warn avahi-daemon[9321]: WARNING: Failed to contact D-Bus daemon.
May 19 00:45:12 alpine daemon.info avahi-daemon[9321]: avahi-daemon 0.8 exiting.
May 19 00:45:12 alpine daemon.err /etc/init.d/avahi-daemon[9299]: ERROR: avahi-daemon failed to start

你大概会看到这样的日志

这个 dbus 很重要

所以 要先安装 dbus

# 安装 dbus
apk add dbus

# 启动 dbus 服务
service dbus start

# 安装 avahi
apk add avahi

# 查看运行状态
service avahi-daemon status

这样 通过 主机名 + .local 就可以了。

e.g: alpine.local

ping alpine.local

正在 Ping alpine.local [fe80::20c:29ff:fec0:d8a5%13] 具有 32 字节的数据:
来自 fe80::20c:29ff:fec0:d8a5%13 的回复: 时间<1ms
来自 fe80::20c:29ff:fec0:d8a5%13 的回复: 时间=1ms
来自 fe80::20c:29ff:fec0:d8a5%13 的回复: 时间<1ms
来自 fe80::20c:29ff:fec0:d8a5%13 的回复: 时间<1ms

fe80::20c:29ff:fec0:d8a5%13 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 0ms,最长 = 1ms,平均 = 0ms
nslookup alpine.local
服务器:  UnKnown
Address:  192.168.50.1

*** UnKnown 找不到 alpine.local: Non-existent domain

大功告成

还好我对主机的命名非常讲究,现在主机和主机之前的通讯都可以通过域名来指定了,即使 IP 发生了变化,也不用我做任何配置,这比传统 DNS 还要省力。

mDNS真是个好东西。

预测下,我接下来的某些软件可能会加入 mDNS 支持。

reference: