avahi 和 nsswitch.conf 带有 `mdns4` 和来自同级的子域解析

Jas*_*ban 5 networking avahi zeroconf

跟进此问题中未答复的评论。

我正在尝试将 zeroconf/bonjour 用于需要将某些流量传递到其他设备的家庭网络专用网络设备 - 如果我可以让它工作,带有额外主机名的 zeroconf 似乎是最简单和最灵活的方法。

我在 avahi-deamon 的第一次传球让我的希望破灭了,因为每个主机可能只能注册一个名字。但是后来我发现上面链接的 SO 帖子及其参考资料向我建议它可能只是一个配置。我相信我根据建议配置了我的系统,但是来自同一设备或其他机器的 teriary-domain 的名称解析仍然无法正常工作。所以我不知道是我做错了还是不可能,我误解了文档。

随着hosts: files mdns4 [NOTFOUND=return] resolve [!UNAVAIL=return] dns/etc/nsswitch.conf-预计修复名称解析所有的网络客户端一台主机上这一变化?或者这只是期望修复每个客户端的名称解析策略,并且必须应用于所有希望参与非最小 zeroconf 名称解析的客户端?

这些可能是愚蠢的问题,但我相信 avahi 使用 nss 来确定它是否应该响应zeroconf 名称解析查询,或者其他什么。另外,如果它在本地工作而不是在其他机器上工作,我会相信它需要在任何地方应用 - 但由于它甚至无法在本地解析名称(配置更改的地方),那么我想我只有错了。我可以期待什么工作?

小智 7

从技术上讲,请求的/先前的行为违反了 mDNS 规范;因此请了解所出现的兼容性问题。您现在需要使用显式映射或第三方工具与 Avahi 来获得所需的结果。

您也可以使用旧版本来nss-mdns解决这个问题(它似乎在转发到 Avahi 之前解析到主机,后续版本似乎已经删除了此类支持)。但这仅适用于以这种方式配置的每个系统,请参阅下面的详细说明。

违反规范

RFC 6762,第 3 节 - 多播 DNS 名称

本文档允许任何计算机用户选择为其计算机提供以下形式的本地链接多播 DNS 主机名:“single-dns-label.local.”。...本文档建议为点本地主机名(即 DNS“A”和“AAAA”记录的名称,将名称映射到 IPv4 和 IPv6 地址)使用单一平面命名空间,但其他 DNS 记录类型(例如(如基于 DNS 的服务发现 [RFC6763] 使用的标签)可以包含适合所需用途的尽可能多的标签。

这似乎意味着 mDNS 不正式支持子域。这似乎也通过其他实现/平台得到了加强:

Windows 不支持此

我唯一失望的是 Bonjour/Avahi 的 Windows 实现不支持该实现声明的别名,它只会看到通常声明的主 avahi 主机名(即上面示例中的 server.local)。

macOS 不支持此功能

如果名称具有两个以上标签(如 foo.bar.local 的情况),它将返回错误。

的自述文件nss-mdns确实引用了一些规则,最小变体使用这些规则来决定是否应将它们发送到 Avahi 进行处理。我在github 存储库上看到了这条评论nss-mdns,它提供了一些上下文日期:

双标签限制启发式在 Mac OS X v10.5 中实现,发布于 2007-10-26 单播 SOA 启发式在 Mac OS X v10.6 中实现,发布于 2009-08-28

这些规则是在2018 年初的0.11版本nss-mdns中引入的,距上一版本已有十多年了0.10,相关变更日志说明:

nss-mdns现在实现了用于检测单播解析的标准启发式方法,并在本地服务器响应请求.local时自动禁用解析.local

您引用的 AskUbuntu 问题表示,该更改可能是从 Ubuntu 18.10 版本引入的,这是可以理解的,因为 18.04 本来是 LTS 版本,因此更新不太可能获得批准。

这表明nss-mdns之前由于长时间缺乏维护/更新而没有遵循此类更改,Apple 的这两项更改都是0.10nss-mdns. 作为相关的github问题通过反向查找逻辑及其造成的缺点/风险所阐明的那样。

有一个长期存在的错误报告,要求 mdns 进行查询以解决该问题,该错误报告会阻塞直到超时,然后才回退到标准 DNS,这可以理解地给用户带来了很多问题,特别是那些与非 mdns 交互的用户.localMicrosoft Active Directory 中的非 mdns FQDN 交互的用户。

为了获得旧的行为,我认为你可能需要恢复0.10nss-mdns.

另一个问题是,到 2020 年,虽然据说 Windows 10 正在改进其 mDNS 支持,但 Android 仍然缺乏它(除了开发人员在其应用程序中明确配置此类支持之外)。有一些解决方法,例如 Unbound 或 CoreDNS,它们都具有将单播 DNS 查询转发到多播 DNS 查询的插件,但是需要配置 Avahi,以便主机公布已发布的地址,以便可以发现它们。

阿瓦希和 NSS

名称服务交换机(NSS)用于您的本地系统处理查找查询,在这里它可以推迟到您的/etc/hosts本地 DNS、systemd-resolvedmDNS 等。大多数软件都会利用它,但情况并非总是如此,尤其是一些实用程序,例如hostdigdrillnslookup它们都会绕过它并直接查询 DNS。

Avahi 不遵循 NSS,而是 NSS 通过 遵循 Avahi nss-mdns。因此,它与如何处理通过网络上其他设备发出的外部请求无关。您可以使用 来测试 Avahi 的查询,而无需涉及 NSS avahi-resolve --name myhostname.local --verbose

我相信 mDNS 的其他实现可能在配置方面更加严格/有限,因此请记住,无论如何,任何 Windows 和 macOS 客户端都可能无法工作,类似于它们仅处理.localmDNS 的 TLD 的方式。

配置 Avahi 以响应多个主机名

可以配置nss-mdns为允许通过解析其他标签/etc/mdns.allow(当您的行中不使用最小/etc/nsswitch.conf hosts:变体时)。如果没有这个,任何使用 NSS 的东西都可能会发送单播 DNS 查询,从而跳过 mDNS。

配置后,您可能需要重新启动任何进程才能重新加载该配置,或者您可以使用 CLI 命令进行测试,例如ping. 虽然这确实允许预期的解析行为,但您会注意到常见的 5 秒超时响应。Avahi 本身无法找到查询响应的命中,因为没有设置任何内容来响应该主机名。

此外,该文件/etc/avahi/avahi-daemon.conf不支持或 的.值,这些值适用于单个标签。但是,您可以使用 avahi-publish 手动发布显式映射:host-namedomain-name

avahi-publish -a -R test.hostname.local 192.168.1.42
Run Code Online (Sandbox Code Playgroud)

守护进程将对此做出响应,但不会将其报告为可通过 发现avahi-browse -a。该-R选项很重要,因为它允许您针对同一 IP 地址进行发布(否则会抱怨本地名称冲突)。或者,您也可以定义这些,/etc/avahi/hosts每行是 IP 地址,后跟主机名(同样可以有一个.),该位置的现有文件中应该有一些注释和示例。基于文件的方法没有与 选项等效的选项-Ravahi-publish因此指定已映射到主机名的 IP 地址将被忽略。avahi-daemon修改此主机文件时不需要重新启动。

请注意,对于无法avahi-resolve正常工作的查询,您需要将 NSS 配置为使用非最小mdns 变体,例如mdns4,范围限定为 IPv4(而不是mdns也涵盖 IPv6)也可以带来更快的结果(而不是等待 5 秒)超时,然后收到 IPv4 响应,avahi-resolve无论如何都会立即响应)。/etc/nsswitch.conf您还可以在不修改的情况下测试查询getent --service=mdns4 hosts test.hostname.local,将--service值更改为mdns4_minimal,mdns等。

Avahi 通过 D-Bus

提供显式 IP 地址有点违背了目的,但如果设备运行 Avahi,您应该能够通过脚本/程序通过 D-Bus 与 Avahi 通信,让它列出主机名的一系列标签/子域API,就像这个旧的 python一样,他们将答案片段移至Github 存储库,该存储库有相当多的分支,其中包括一个在旧代码尚未老化时移植到 python3 的分支。对于 Docker 用户来说,在搜索 avahi 镜像时可以在 DockerHub 上找到类似的内容,我相信有一个与 Traefik 和 docker 标签集成的镜像,可以通过 Avahi 通过 mDNS 公开容器。

Avahi 用于 DNS-SD

您仍然可以利用 mDNS,因为它通常与打印机等设备中的 DNS-SD(服务发现)一起使用。您可以提供一个友好的字符串作为服务名称,并指示服务类型。然后,另一台设备可以使用 DNS-SD 查询感兴趣的设备并与它们交互。

另一种可行的替代方案是动态 DNS (DDNS),它允许设备更新其 IP 地址的 DNS 记录。还有更多涉及的服务发现软件,例如 Hashicorp Consul。