Avahi
摘自 維基百科的 Avahi 條目:
- Avahi 是一種自由的零配置網絡(zeroconf)實現,其中包括用於通過組播 DNS/DNS-SD 發現服務的系統。它允許程序在無需特別配置的情況下,發布和發現區域網上運行的服務與主機。例如,連接到網絡後,你便可以立即發現可用的印表機、可訪問的文件以及可以與之通信的其他用戶。Avahi 採用 GNU 寬通用公共許可證(LGPL)授權。
安裝
安裝 avahi包 軟體包,並啟用 avahi-daemon.service;如果希望使用套接字激活,也可以啟用 avahi-daemon.socket。
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 支持,systemd-resolved 仍會響應這些查詢。參見 #systemd-resolved 導致 nss-mdns 無法工作。
- 有關 NSS 配置的更多信息,請參閱 nss-mymachines(8) 和 Avahi 文檔。
為自定義頂級域名配置 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 客戶端無法通過 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
mdns_minimal 而不是 mdns。Avahi 套接字出現 ECONNREFUSED(連接被拒絕)錯誤
如果 Avahi 實例能夠正常啟動和運行,但 NSS 似乎沒有將請求轉發給 mDNS,可能是套接字 /run/avahi-daemon/socket 處於卡住的狀態。例如,可以通過 strace 驗證。在這種情況下,可能需要同時重啟 avahi-daemon.service 和 avahi-daemon.socket,才能恢復正常工作。
參見
- Avahi — 項目官方網站
- 維基百科:Avahi(軟體)
- iTunes(包含 Bonjour) — 在 Windows 上啟用 Zeroconf
- http://www.zeroconf.org/