Avahi: анонсируем сервис за другой хост
Есть очень “хороший” кусок кода, который называется Avahi. Этот код имплементирует mDNS (DNS-SD) кроссплатформенно и работает как минимум под *NIX, BSD, macOS (ЕМНИП) и позволяет публиковать для локальной сети сервисы (например, SMB-шары, Time Machine, да и вообще все, что душе угодно).
Не зря я взял “хороший” в первом предложении в кавычки, ибо во время настройки сего добра я споткнулся (и довольно болезненно) о пару подводных камней, которые опишу тут.
В этом посте будем предполагать, что мы хотим опубликовать инфу о SMB шарах и Time Machine с помощью Avahi, чтобы мышевозненько подключаться к файлопомойке и бэкапить мак.
Так как у меня Samba работает в клетке - я не могу просто так взять и запустить в клетке avahi, чтобы оно работало, потому что клетка - не виртуальная машина и шарит сетевой стек с хостом. Следовательно, avahi на хосте и в клетке друг друга иногда перекрывают, и вы можете наблюдать ситуацию, когда сервис, опубликованный через Avahi то доступен, то нет. Решением этой проблемы будет сей гайд, который позволит Avahi на хосте публиковать сервисы в mDNS, которые запущены в клетках.
Камень раз - статичные хосты
Самое простое, что можно использовать для публикации сервиса - это, собственно, хостнейм сервиса и фаерволом заворачивать нужный трафик на нужный IP клетки. Мне такое решение показалось костыльным, и в итоге я нагуглил возможность задать статичное mDNS имя для IP адреса клетки с помощью файла hosts
. Нет, это не /etc/hosts
, а /usr/local/avahi/hosts
в FreeBSD и /etc/avahi/hosts
в Linux. Синтаксис у этого файла идентичен с /etc/hosts
, поэтому я сделал так:
192.168.1.200 fileserver.local
И сразу же напоролся на проблему - я не мог с помощью mDNS отрезолвить IP адрес. Как оказалось, проблема в том, что Avahi, к которой приложил руку Поттеринг (намек, ага), просто не умеет в Primary IP, то есть чтобы имя хоста сервера публиковалось только для указанного первичного IP адреса (например, указанного в конфиге) и биндится сразу на все доступные адреса доступных или завайтлистеных в конфиге интерфейсов. И чтобы успешно опубликовать адрес, мне пришлось добавить в hosts-файл самого Avahi еще и ip-хост связку самой хост машины:
192.168.0.3 eburg.local
192.168.1.200 fileserver.local
И после перезапуска обе записи успешно опубликовались, чему я несказанно рад :)
Камень два - файл описания сервиса
Для начала рабочий пример для Samba и Time Machine:
<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">fileserver</name>
<service>
<type>_smb._tcp</type>
<host-name>fileserver.local</host-name>
<port>445</port>
</service>
<service>
<type>_adisk._tcp</type>
<txt-record>sys=waMa=0,adVF=0x100</txt-record>
<txt-record>dk0=adVN=Time Capsule,adVF=0x82</txt-record>
<host-name>fileserver.local</host-name>
</service>
</service-group>
Первое, с чем вы можете столкнуться - это с правильным обозначением имени хоста и имени отображения сервиса. Параметр name
отвечает только за отображение, и каждый вложенный сервис должен иметь параметр host-name
с именем хоста, которое можно отресолвить.
Второе - это сама суть параметра host-name
. Там должен быть именно домен, указание IP адреса не допускается.