Avahi
- Avahi 是一个自由的 零配置网络 (zeroconf) 实现,包括用于组播 DNS/DNS-SD 服务发现的系统。它允许程序发布和发现本地网络上运行的服务和主机,而无需特定的配置。例如,您可以插入网络并立即找到打印机进行打印、文件进行查看以及人员进行交谈。它在 GNU Lesser General Public License (LGPL) 下获得许可。
安装
安装 avahi 软件包并启用 avahi-daemon.service
或使用 套接字激活。
systemd-resolved.service
。使用 Avahi
主机名解析
Avahi 使用 "hostname.local" 命名方案提供本地主机名解析。要启用它,请安装 nss-mdns 软件包并启动/启用 avahi-daemon.service
。
然后,编辑文件 /etc/nsswitch.conf
并更改 hosts
行,在 resolve
和 dns
之前包含 mdns_minimal [NOTFOUND=return]
hosts: mymachines mdns_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns
- 如果您在解析
.local
主机时遇到速度减慢的问题(或者您不想使用 IPv6),请尝试使用mdns4_minimal
和mdns4
分别代替mdns_minimal
和mdns
。 - 上面的行使
nss-mdns
对.local
域具有权威性,除非您的单播 DNS 服务器响应顶级local
名称的SOA
查询,或者请求的标签超过两个。请参阅nss-mdns
激活说明。- systemd-resolved 即使其 mDNS 支持被禁用,也会响应这些查询。请参阅 #systemd-resolved 阻止 nss-mdns 工作。
- 有关 nss 配置的更多信息,请参阅 nss-mymachines(8) 和 Avahi 文档。
为自定义 TLD 配置 mDNS
mdns_minimal
模块仅处理对 .local
TLD 的查询。请注意 [NOTFOUND=return]
,它指定如果 mdns_minimal
找不到 *.local
,它将不会继续在 dns
、myhostname
等中搜索。
如果您希望 Avahi 支持其他 TLD,您应该
- 用完整的
mdns
模块替换mdns_minimal [NOTFOUND=return]
。还有仅 IPv4 和仅 IPv6 模块mdns[46](_minimal)
- 使用您选择的
domain-name
自定义/etc/avahi/avahi-daemon.conf
- 在
/etc/mdns.allow
中将 Avahi 自定义 TLD 列入白名单
工具
Avahi 包含几个实用程序,可帮助您发现网络上运行的服务。例如,运行此命令以发现网络中的服务
$ avahi-browse --all --ignore-local --resolve --terminate
如果此命令没有产生任何结果,则可能是由于防火墙阻止了 mDNS 流量。
如果您只想执行 mDNS 查询以将 .local 主机名解析为 IP 地址(类似于 dig 或 nslookup),请使用
$ avahi-resolve-host-name some-host-name.local
请注意,getent hosts
命令可以同时执行 DNS 和 mDNS 查找。
Avahi Zeroconf 浏览器 avahi-discover
显示您网络上的各种服务。请注意,它需要 Avahi 的可选依赖项 gtk3、python-dbus 和 python-gobject。您还可以分别使用 bssh
和 bvnc
浏览 SSH 和 VNC 服务器。
防火墙
如果您正在使用防火墙,请务必打开 UDP 端口 5353
。
链路本地 (Bonjour/Zeroconf) 聊天
Avahi 可用于 Linux 下的 Bonjour 协议支持。查看 Wikipedia:即时通讯客户端比较 或 应用程序列表/互联网#即时通讯客户端 以获取支持 Bonjour 协议的客户端列表。
获取 IPv4LL IP 地址
dhcpcd 客户端可以尝试获取 IPv4LL 地址,如果它未能通过 DHCP 获取地址。默认情况下,此选项已禁用。要启用它,请注释掉 noipv4ll 字符串
/etc/dhcpcd.conf
... #noipv4ll ...
或者,运行 avahi-autoipd
# avahi-autoipd -D
添加服务
Avahi 会通告在 /etc/avahi/services
中找到 *.service
文件的服务。此目录中的文件必须可由 avahi
用户/组读取。
如果您想通告没有 *.service
文件的服务,则创建自己的文件非常容易。例如,假设您想通告在 TCP 端口 17
上运行的每日名言 (QOTD) 服务,该服务按照 RFC:865 运行在您的机器上
首先要做的是确定 <type>
。avahi.service(5) 指出类型应为“此服务的 DNS-SD 服务类型。例如 '_http._tcp'”。由于 DNS-SD 注册表于 2010 年合并到 IANA 注册表中,我们在 IANA 注册表 或 /etc/services
文件中查找服务名称。那里显示的服务名称是 qotd
。由于我们正在 tcp 上运行 QOTD,我们现在知道该服务是 _qotd._tcp
,端口(根据 IANA 和 RFC 865)是 17
。
因此,我们的服务文件是
qotd.service
<?xml version="1.0" standalone='no'?><!--*-nxml-*--> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">%h</name> <service> <type>_qotd._tcp</type> <port>17</port> </service> </service-group>
对于更复杂的场景,例如通告在不同服务器上运行的服务、DNS 子类型等等,请查阅 avahi.service(5)。
请记住,Avahi 不支持 <type> 字段中的任意字符串,您只能设置 Avahi 服务数据库中已知的值。如果您想注册一些自定义内容,您可能需要编辑数据库定义,构建更新的版本并将其分发给您的主机。
SSH
Avahi 附带一个示例服务文件来通告 SSH 服务器。要启用它
# cp /usr/share/doc/avahi/ssh.service /etc/avahi/services/
文件共享
NFS
如果您设置了 NFS 共享,则可以使用 Avahi 在 Zeroconf 启用的浏览器(例如 KDE 上的 Konqueror 和 macOS 上的 Finder)或文件管理器(例如 GNOME/文件)中自动挂载它们。
在 /etc/avahi/services
中创建一个包含以下内容的 .service
文件
/etc/avahi/services/nfs_Zephyrus_Music.service
<?xml version="1.0" standalone='no'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">NFS Music Share on %h</name> <service> <type>_nfs._tcp</type> <port>2049</port> <txt-record>path=/data/shared/Music</txt-record> </service> </service-group>
如果您的 /etc/exports
中有 insecure 选项,则端口是正确的;否则,需要更改端口(请注意,macOS 客户端需要 insecure)。路径是您的导出路径或其子目录。由于某种原因,自动挂载功能已从 Leopard 中删除,但是 一个脚本可用。这是基于 此帖子。
Samba
在服务器和客户端上都运行 Avahi 守护程序的情况下,客户端上的文件管理器应自动找到服务器。
Vsftpd
您还可以自动发现常规 FTP 服务器,例如 vsftpd。安装 vsftpd 软件包并根据您自己的个人偏好更改 vsftpd 的设置(请参阅 ubuntuforums.org 上的此线程 或 vsftpd.conf(5))。
在 /etc/avahi/services
中创建一个包含以下内容的 .service
文件
/etc/avahi/services/ftp.service
<?xml version="1.0" standalone='no'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name>FTP file sharing</name> <service> <type>_ftp._tcp</type> <port>21</port> </service> </service-group>
FTP 服务器现在应该由 Avahi 通告。您现在应该能够从网络中另一台计算机上的文件管理器中找到 FTP 服务器。您可能需要在客户端上启用 #主机名解析。
故障排除
主机名更改并附加递增的数字
这是一个 已知错误,由主机名竞争条件引起。一种可能的解决方法是禁用 IPv6 以尝试防止竞争条件。如果存在多个接口,请使用 allow-interfaces 将 Avahi 限制为单个接口。另一种可能的解决方法是禁用缓存 以完全阻止 Avahi 检查主机名冲突,但这会阻止 Avahi 执行查找。
systemd-resolved 阻止 nss-mdns 工作
nss-mdns 仅在 /etc/resolv.conf
中列出的 DNS 服务器对 "local" 域的 SOA 查询返回 NXDOMAIN
时才有效。[1]
首先检查您配置的 DNS 服务器是否使用 NXDOMAIN
回答 "local" 域的 SOA 查询。例如
$ host -t SOA local
如果 DNS 服务器响应 NXDOMAIN
,则您无需执行以下步骤。即使使用 systemd-resolved,Avahi 也应该能够正常找到网络中的资源。
在旧版本的 systemd-resolved 中,resolved.conf(5) 中 MulticastDNS=no
的全局设置导致 "local" 域的 Avahi 不兼容的响应代码。这导致 Avahi 无法正确找到资源(打印机)。有关参考,请参阅 systemd 问题 21659。
但是,如果上面的 DNS 查询未能为 "local" 域返回 NXDOMAIN
,则可以使用完整的 mdns
NSS 模块代替 mdns_minimal
,并创建 /etc/mdns.allow
以仅允许 "local" 域。例如
/etc/nsswitch.conf
hosts: mymachines mdns [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns
/etc/mdns.allow
.local. .local
mdns_minimal
而不是 mdns
。ECONNREFUSED (连接被拒绝) 在 avahi 套接字上
如果您的 Avahi 实例启动并正确运行,但 nss 似乎没有将请求转发到 mdns,则可能是由于套接字 /run/avahi-daemon/socket
卡住。例如,可以使用 strace 验证这一点。在这种情况下,您可能需要重启 avahi-daemon.service
和 avahi-daemon.socket
以使其正常工作。
KDE Connect 内置 mDNS 冲突
如果您使用 kdeconnect,则 avahi 会存在 mDNS 冲突,因为 kdeconnect 也运行其 mdns 服务器。这可能会导致主机名冲突,例如在网络重启后将您的主机重命名为 myhostname-2
。
要纠正此问题,请删除 kdeconnect,或构建不带 mDNS 支持的版本,例如 kdeconnect-no-mdnsAUR 中的版本。
请参阅 kde 错误 487719。
参见
- Avahi - 官方项目网站
- Wikipedia:Avahi (软件)
- iTunes (包含 Bonjour) - 在 Windows 上启用 Zeroconf
- http://www.zeroconf.org/