Локальный распределенный DNS без DNS: Multicast DNS (mDNS)

Введение


У вас есть два линукс изделия (другие тоже будут работать, но вам надо гуглить зачем) между которыми вы ходите уметь общение.

Самый простой вариант это по ip, но только один раз. Завтра изделие получит другой ip и это никак не победить.

Самый простой вариант это добавить в /etc/hosts файл алиас:

192.168.0.48 destination

А во всех скриптах использовать алиас, например:

$ scp kitty.gif user@destination:

Но ip всё равно меняется. Но менять уже в одном месте. Но менять всё же надо.

Самый просто вариант это починить это установить локальный DNS сервер на сервере и сделать его главным в сети и проксировать все запросы через него нет такого.

А ведь было бы здорово не менять это вручную да?

Multicast DNS (mDNS)


В 2025 году 25 лет назад придумали Multicast DNS (mDNS) который через бродкаст запросы делает динамический распределённый локальный DNS о котором не надо беспокоиться и который просто работает. Но только в одной сети. И только один хост на изделие.

Как Multicast DNS (как mDNS)


В линуксе оно когда конвертирует слова-имена в цифры оно делает через сервис Name Service Switch. У этого сервиса есть /etc/nsswitch.conf где ему указано где как искать:

> cat /etc/nsswitch.conf
# Name Service Switch configuration file.
# See nsswitch.conf(5) for details.

passwd: files systemd
group: files [SUCCESS=merge] systemd
shadow: files systemd
gshadow: files systemd

publickey: files

hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
networks: files

Для хостов оно говорит сначала искать в (mymachines) в локальных контейнерах.

Потом оно ищет в (systemd-resolved) dns который заменил собой nss-dns. Если DNS возвращает недоступно, то конец, не искать.

Потом смотрит в /etc/hosts, на локальный хостнейм и потом уже в легаси DNS.

Занимательный факт: мы можем добавить ещё сервис в этот лист. Что если мы добавим Multicast DNS (mDNS)?

Установка Multicast DNS (установка mDNS)

Совершенно абсолютно очевидно что на каждом изделии мы будем делать и серверную, и клиенсткую части. Поэтому всё что ниже нужно сделать везде чтобы была гармония.

https://wiki.archlinux.org/title/Avahi

Устанавливаем пакет libnss-mdns в котором будет avahi (мы добавим в NSS hosts как сервис):

# pacman -Sy nss-mdns
# emerge -av sys-auth/nss-mdns
# sudo apt-get install libnss-mdns avahi-daemon avahi-utils

Дальше добавим /etc/nsswitch.conf строку mdns_minimal [NOTFOUND=return]:

# hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
hosts: mymachines mdns_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns
# hosts: mymachines mdns_minimal resolve [!UNAVAIL=return] files myhostname dns

[NOTFOUND=return] говорит не искать дальше домены *.local, это сломает локальные записи в /etc/hosts поэтому можно удалить чтобы работало как раньше, но лучше.

Ещё можно перехватывать на только *.local домены, но нам это не нужно. Для этого мы будем использовать /etc/hosts

Устанавливаем наш локальный домен в файле /etc/avahi/avahi-daemon.conf и перезапускаем и проверяем:

$ cat /etc/avahi/avahi-daemon.conf | grep host-name

host-name=source

$ systemctl enable avahi-daemon.service # add to autorun
$ systemctl restart avahi-daemon.service # run

$ avahi-browse --all --verbose --resolve --terminate

$ avahi-resolve-host-name source.local

source.local	192.168.100.101
  
$ ping source.local

PING source.local 56 data bytes
64 bytes from source.local : icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from source.local : icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from source.local : icmp_seq=3 ttl=64 time=0.056 ms
^C

Проблема в том что у нас может быть 1 хост на одно изделие. Если вы хотите поднимать несколько разных локальных доменов например:

git.local
server.local

То это можно легко сделать через /etc/avahi/hosts, но там тоже надо хардкодить ip.

Самый простой способ это починить это при поднятии сети запускать несколько раз avahi-publish & на каждый домен каждый раз вычисляя динамически локальный ip а никак живите с одним доменом всё лучше чем ничего.

Включаем sftp/ssh


$ cp /usr/share/doc/avahi/sftp-ssh.service /etc/avahi/services/
$ cp /usr/share/doc/avahi/ssh.service /etc/avahi/services/

$ systemctl restart avahi-daemon.service

Второе изделелие


Быстренько повторяем всё что сверху на втором изделии, потом ищем их друг у друга проверяем что всё работает. Настраиваем ssh подключение по ip между двумя изделиями. Потом в ssh просто меняем ip на локальный домен:

$ ssh my_user@destination.local -i ~/.ssh/my_key

Когда всё работает мы добавляем ~/.ssh/config эти волшебные слова:

Host destination
    HostName destination.local
    IdentityFile ~/.ssh/my_key
    User my_user

Магическим образом был создан короткий алиас для ssh в котором всё настроено:

$ ssh destination

Ну вот и всё, теперь мы можем легко обмениваться файлами и удалённо запускать команды:

$ cd /tmp/
$ date > temp_file
$ echo "source" >> temp_file
$ scp temp_file destination:
$ ssh destination 'echo destination >> ~/temp_file'
$ ssh destination 'cat ~/temp_file'

Уру-ру-ру, мы можем посылать файлы и удалённо выполнять команды. А главное теперь есть домены не привязанные к ip!

Выведение


Главный для меня минус в том что нельзя просто сделать несколько доменов на много сервисов на одном изделии, но с этим можно жить!

Зато таким же образом можно сделать и NFS, и rsync, и git!!!

А ещё mDNS лежит в основе IoT и прочих home assistant сетей!

#linux #multicastdns #mdns #dns

2025.09.28 01:53