, последнее обновление:

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 адреса не допускается.