mDNS поверх WireGuard: три шлюза, пока пир не ответит
Avahi нужен подходящий интерфейс, маршрут к группе и пир, которому принадлежит назначение. Три шлюза, три отдельные проверки и никакого разветвления.
Установка флага multicast на устройстве WireGuard делает интерфейс подходящим для программ обнаружения, и на этом действие флага заканчивается. Он не говорит протоколу, куда должен идти групповой пакет, а на устройстве с несколькими пирами нет одного очевидного ответа. Между работающим демоном и обнаруженным сервисом стоят три отдельных шлюза.
Проверяйте их по порядку, потому что прохождение одного ничего не говорит о следующем.
Первый шлюз: флаг и политика демона
Устройство WireGuard в Linux создаётся как соединение точка-точка без ARP и по умолчанию не несёт флаг multicast. Добавление флага — это локальное изменение интерфейса, выполняемое тем, что управляет устройством. У Avahi поверх этого собственный взгляд на мир, и его политика по умолчанию полностью пропускает интерфейсы точка-точка. Поэтому до движения хотя бы одного пакета применяются две независимые проверки пригодности.
Значит, демону нужно явное решение, а не просто работающий процесс. Его документированные средства управления включают allow-interfaces, deny-interfaces и allow-point-to-point, и последний — та настройка, которую люди упускают.
Проверки ниже сообщают флаги соединения, маршрут multicast и то, разбирается ли конфигурация демона вообще:
ip -d link show wg0
ip route get 224.0.0.251
avahi-daemon --check
Успешно запущенный демон не обязательно открыл сокеты на том интерфейсе, который вам важен. Читайте его действующую конфигурацию, а не предполагайте, что состояние службы равно покрытию.
Второй шлюз: маршрут к группе
Второй шлюз — обычная маршрутизация. Пакет, адресованный 224.0.0.251, следует таблице пересылки, как и всё остальное, и если таблица отправляет его через физический интерфейс LAN, никакая конфигурация WireGuard этого не изменит. Сначала исправьте маршрут, и остаток расследования станет короче. Посмотрите, что ядро сообщает об адресе группы, прежде чем трогать какие-либо ключи пиров.
| Observation | Gate it belongs to | What it does not prove |
|---|---|---|
Multicast flag present on wg0 | Interface eligibility | The daemon will use the interface |
Route to the group via wg0 | Forwarding | Any peer will receive it |
| Destination inside a peer's allowed list | Peer selection | That peer's network will answer |
Без конкретного маршрута ядро возвращается к собственной обработке multicast соединения, поэтому по умолчанию всё выглядит правильно в плоской LAN и неправильно, как только тот же групповой трафик должен выйти через туннель. Сбой незаметен со стороны отправителя: запрос уходит куда-то, а ответ никогда не приходит.
Третий шлюз: WireGuard выбирает одного пира на пакет
WireGuard выбирает исходящий пир, ища назначение в наборах разрешённых адресов, и путь передачи Linux выполняет этот поиск один раз на пакет. Результат один, и пакет шифруется для этого пира. Один и тот же префикс группы в разрешённых списках нескольких пиров не создаёт членства или репликации; он создаёт неоднозначный поиск, который разрешается на одном из них.
На выделенном соединении с двумя концами это именно то, что нужно, потому что у намеренно переносимого группового трафика есть один предназначенный получатель. На интерфейсе с пятью пирами это ограничение, а не возможность, и исправление относится к проектированию, а не к конфигурации отдельного пира.
Проекту с разветвлением нужен явный ретранслятор, отдельные соединения или совершенно иной механизм обнаружения. Публикация рецепта для двух концов как решения для множества клиентов потому, что каждый клиент может пинговать шлюз, — это способ развернуть всё неправильно.
Входящее направление проверяется иначе: источник полученного пакета должен попадать в разрешённый список аутентифицированного пира. Добавление туда multicast-назначения не заменяет реальное владение источником отправителя.
Отражение — это граница, а не мост
Отражатель Avahi воспроизводит сообщения mDNS между выбранными интерфейсами на прикладном уровне. Это граница обнаружения между сетями, а не Ethernet-мост и не общий multicast-маршрутизатор. Два отражателя, подключённые к одним и тем же сетям, с удовольствием создадут петлю повторяющихся объявлений.
Отражение также передаёт имена служб и их метаданные в другую сеть, что является решением о приватности не меньше, чем решением о маршрутизации. Ограничьте выбранные интерфейсы и используйте фильтры служб там, где установленная версия их поддерживает, чтобы границу пересекали только объявления, нужные уполномоченному пользователю.
Обнаружение и использование остаются отдельными результатами. Клиент может видеть объявление службы, объявленный адрес которой недоступен с того места, где находится клиент, или порт которой отклоняется его политикой доступа. Подтвердите соединение со службой после появления объявления, и если приложение поддерживает стабильное DNS-имя или явный адрес сервера, предпочтите это расширению локального обнаружения соединения. Описание маршрутизации по криптоключу охватывает выбор пира по назначению, от которого всё это зависит.