Hatred's Log Place

DON'T PANIC!

Feb 28, 2020 - 3 minute read - linux

mDNS stopped working

В один прекрасный момент, на ровном месте перестал работать mDNS и перестали резолвится хосты в зоне .local.

При этом демон Avahi был запущен, сервис systemd-resolved остановлен и в /etc/nsswitch.conf всё в порядке (присутствуют mdns4_minimal и mdns4, в общем, всё как в ArchWiki).

Более того, вызов:

avahi-resolve -n 35002201.local

завершается успешно и возвращает адрес хоста.

Исследование привело к команде getent. Вызов:

getent hosts 35002201.local

выдал пустой результат. Хмм… как говорит документация, эта утилита точно работает через NSS.

Что делает пытливый ум линуксоида в таком случае? Правильно! Запускает команду через strace (я убрал лишний вывод, оставил только суть):

$ LANG=C strace -f getent hosts 35002201.local
execve("/usr/bin/getent", ["getent", "hosts", "35002201.local"], 0x7ffef387b638 /* 98 vars */) = 0
brk(NULL)                               = 0x5618ad268000
...
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=372, ...}) = 0
read(3, "# Name Service Switch configurat"..., 4096) = 372
read(3, "", 4096)                       = 0
close(3)                                = 0
...
openat(AT_FDCWD, "/usr/lib/libnss_mdns4_minimal.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=18104, ...}) = 0
mmap(NULL, 20496, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2bef77a000
mmap(0x7f2bef77b000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f2bef77b000
mmap(0x7f2bef77d000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f2bef77d000
mmap(0x7f2bef77e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f2bef77e000
close(3)                                = 0
...
openat(AT_FDCWD, "/etc/mdns.allow", O_RDONLY) = -1 ENOENT (No such file or directory)
...
exit_group(2)                           = ?
+++ exited with 2 +++

Хмм… А что это за файл /etc/mdns.allow, который во моей системе отсутствует? Читаем и видим, что рекомендованная конфигурация - это отсутствие этого файла. Всё как у меня. Тогда, выполняется некоторая эвристика:

  • Если запрос не заканчивается на .local. или .local, он отклоняется
  • Если в запросе есть точка (появяляется домент третьего уровня, например foo.bar.local), то он тоже отклоняется
  • Если системный unicast DNS (если проще: обычный DNS, работающий через 53 порт), указанный в /etc/resolv.conf отдаёт SOA запись для local, запрос тоже отклоняется. Иными словами, запрос отклоняется, если запрос host -t SOA local верунл что-то отличное от Host local not found: 3(NXDOMAIN).

Хм, а вот третий пункт уже интересней. Вводим команду и видим:

$ host -t SOA local
local has SOA record ns1.inetvl.ru. support.inetvl.ru. 2017062801 28800 3600 1209600 86400

Оппа… Создаём файл /etc/mdns.allow со следующим содержимым:

.local.
.local

И пробуем:

$ getent hosts 35002201.local
192.168.101.2   35002201.local

$ ping 35002201.local
PING 35002201.local (192.168.101.2) 56(84) bytes of data.
64 bytes from 35002201.local (192.168.101.2): icmp_seq=1 ttl=64 time=0.216 ms
64 bytes from 35002201.local (192.168.101.2): icmp_seq=2 ttl=64 time=0.271 ms
64 bytes from 35002201.local (192.168.101.2): icmp_seq=3 ttl=64 time=0.247 ms
^C
--- 35002201.local ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2029ms
rtt min/avg/max/mdev = 0.216/0.244/0.271/0.022 ms

Ура!

Выводы

Только два:

  1. При обновлении системы убрали дефолтный /etc/mdns.allow. Но пакеты, где бы он мог находиться в последнее время не обновлялись.
  2. Изменились настройки сети провайдера

Собственно, скорее всего пункт 2.