跳至內容

Avahi

出自 Arch Linux 中文维基

摘自 維基百科的 Avahi 條目:

Avahi 是一種自由的零配置網絡(zeroconf)實現,其中包括用於通過組播 DNS/DNS-SD 發現服務的系統。它允許程序在無需特別配置的情況下,發布和發現區域網上運行的服務與主機。例如,連接到網絡後,你便可以立即發現可用的印表機、可訪問的文件以及可以與之通信的其他用戶。Avahi 採用 GNU 寬通用公共許可證(LGPL)授權。

安裝

安裝 avahi包 軟體包,並啟用 avahi-daemon.service;如果希望使用套接字激活,也可以啟用 avahi-daemon.socket。

注意:systemd-resolved 內置了 mDNS 服務。在使用 Avahi 之前,請確保已禁用 systemd-resolved 的組播 DNS 解析器/響應器,或者直接禁用 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 的啟用說明。

為自定義頂級域名配置 mDNS

mdns_minimal 模塊僅處理針對 .local 頂級域名(TLD)的查詢。注意 [NOTFOUND=return]:它表示如果 mdns_minimal 無法找到 *.local 主機,就不會繼續通過 dns、myhostname 等模塊進行查找。

如果希望 Avahi 支持其他頂級域名,需要:

  • 將 mdns_minimal [NOTFOUND=return] 替換為完整的 mdns 模塊。此外還有僅支持 IPv4 或 IPv6 的模塊 mdns[46](_minimal)。
  • 在 /etc/avahi/avahi-daemon.conf 中將 domain-name 配置為所需的域名。
  • 在 /etc/mdns.allow 中將 Avahi 使用的自定義頂級域名加入允許列表。

工具

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 零配置網絡瀏覽器 avahi-discover 可以顯示網絡上的各類服務。使用該工具需要安裝 Avahi 的可選依賴 gtk3包、python-dbus包 和 python-gobject包。此外,還可以分別使用 bssh 和 bvnc 瀏覽 SSH 和 VNC 伺服器。

防火牆

如果正在使用防火牆,請確保開放 UDP 5353 埠。

鏈路本地(Bonjour/Zeroconf)聊天

Avahi 可用於在 Linux 上提供 Bonjour 協議支持。有關支持 Bonjour 協議的客戶端列表,請參閱 即時通信客戶端比較或應用程式列表/網際網路#即時通訊客戶端。

獲取 IPv4LL IP 地址

本文或本章節可能需要合併到dhcpcd。

附註: 應將此內容合併到主頁面(在 Talk:Avahi 中討論)

如果 dhcpcd 客戶端無法通過 DHCP 獲取地址,可以嘗試獲取 IPv4LL 地址。默認情況下,此功能處於禁用狀態。要啟用它,請將 noipv4ll 一行注釋掉:

/etc/dhcpcd.conf
...
#noipv4ll
...

或者運行 avahi-autoipd:

# avahi-autoipd -D

添加服務

Avahi 會發布 /etc/avahi/services 目錄中 *.service 文件所定義的服務。該目錄中的文件必須可供 avahi 用戶或用戶組讀取。

如果想發布的服務沒有對應的 *.service 文件,可以很方便地自行創建。 例如,假設你想發布一項運行在本機 TCP 17 埠、符合 RFC 865 規範的每日名言(QOTD)服務。

首先需要確定 <type>。avahi.service(5) 指出,其值應為「該服務的 DNS-SD 服務類型,例如 '_http._tcp'」。由於 DNS-SD 註冊表已於 2010 年合併到 IANA 註冊表,因此可以在 IANA 註冊表或 /etc/services 文件中查找服務名稱。該服務在註冊表中的名稱為 qotd。由於 QOTD 使用 TCP,因此其服務類型為 _qotd._tcp,埠為 17(依據 IANA 註冊表和 RFC 865)。

於是可以創建以下服務文件:

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/Files 等文件管理器自動掛載這些共享。

在 /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 的配置(參見 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>

此時 Avahi 應當開始發布該 FTP 伺服器。你應該能夠從區域網中另一台計算機的文件管理器中找到它。客戶端可能還需要啟用#主機名解析功能。

故障排除

主機名末尾不斷追加遞增的數字

如果沒有禁用 systemd-resolved 的組播 DNS 解析器,就可能出現這種情況。此外,這也是一個由主機名競態條件引起的已知問題。一種可能的解決方法是禁用 IPv6,以嘗試避免競態條件。如果存在多個網絡接口,可以使用 allow-interfaces 將 Avahi 限制在單個接口上。另一種可能的解決方法是禁用緩存,從而阻止 Avahi 檢查主機名衝突,但這也會使 Avahi 無法執行查詢。

systemd-resolved 導致 nss-mdns 無法工作

只有當 /etc/resolv.conf 中列出的 DNS 伺服器對「local」域名的 SOA 查詢返回 NXDOMAIN 時,nss-mdns 才能正常工作。[1]

首先檢查當前配置的 DNS 伺服器是否會對「local」域名的 SOA 查詢返回 NXDOMAIN。例如:

$ 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
注意:上述方法會破壞 mtr包 和 traceroute包 等網絡工具的反向 DNS 查詢。這些程序會嘗試通過 Avahi 進行反向解析,在超時後也不會回退到其他 DNS 服務。該問題似乎類似於 Debian 問題 433943;遺憾的是,其中建議使用 mdns_minimal 而不是 mdns。

Avahi 套接字出現 ECONNREFUSED(連接被拒絕)錯誤

如果 Avahi 實例能夠正常啟動和運行,但 NSS 似乎沒有將請求轉發給 mDNS,可能是套接字 /run/avahi-daemon/socket 處於卡住的狀態。例如,可以通過 strace 驗證。在這種情況下,可能需要同時重啟 avahi-daemon.service 和 avahi-daemon.socket,才能恢復正常工作。

參見