Политическая маршрутизация в OpenWrt: цепочка, которая ловит локальный DNS
Запросы клиентов и запросы самого роутера попадают в разные хуки. Политика, нацеленная на prerouting, несёт каждый запрос из LAN и оставляет роутер на канале провайдера.
Клиенты в LAN резолвят через туннель, а собственные запросы роутера тихо этого не делают. Обновления пакетов, синхронизация времени и динамический DNS уходят обычным каналом, тогда как каждый пересланный запрос идёт через VPN, и ничто в интерфейсе не говорит о существовании двух разных путей. Объяснение не в ошибке политики, а в вопросе, какой хук видит пакет. Два потока, один адрес резолвера, и только один из них пересекает роутер. Их разделение — это весь ремонт.
Два потока, один адрес резолвера
Первый поток — тот, который представляют люди. Клиент спрашивает резолвер роутера, резолвер пересылает вверх, и этот пересланный пакет проходит через роутер на выходе. Этот пакет виден всему, что наблюдает за пересланным трафиком.
Второй поток никогда ниоткуда не приходит. Его создаёт роутер, поэтому нет ни входящего пакета, ни шага пересылки для сопоставления.
Оба могут целиться в один и тот же адрес резолвера, и именно поэтому разницу легко не заметить. Та же цель, другое происхождение, другая цепочка. Как только видно происхождение, остальная диагностика следует.
Пересланные и локально созданные пакеты входят по-разному
Пересланный трафик оценивается, когда приходит с другого интерфейса. Пакеты политической маршрутизации показывают это как цепочку prerouting, и правило, помещённое туда, видит каждый пакет, пересекающий роутер. Поэтому запросы клиентов ведут себя ровно так, как описывает политика, и поэтому роутер её игнорирует. Правило не ошибочно, оно просто привязано к хуку, до которого роутер никогда не доходит. Перенесите его, и то же совпадение начнёт работать.
Локально созданный трафик создаётся процессом на роутере и попадает на путь выхода. Его маршрутизирует собственное решение роутера, и оно встречает политику только если политика покрывает эту цепочку. Нет ни входящего интерфейса для сопоставления, ни решения о пересылке для наблюдения.
Это свойство того, где рождаются пакеты, а не какого-то конкретного пакета. Правило, написанное для одной цепочки, просто не имеет мнения о другой. Никакая настройка правил этого не меняет.
Выберите цепочку выхода, затем сузьте совпадение
Исправление — привязать то же намерение и к цепочке выхода или перенести правило туда, когда важны собственные запросы роутера. В установке OpenWrt, построенной на пакете политической маршрутизации, это значит выбрать output вместо prerouting в настройке цепочки правила. Оставьте оба правила, если обеим группам нужно покрытие.
Затем сузьте то, чему соответствует правило. Адреса резолвера назначения на порту, который резолвер действительно использует, — гораздо меньшее решение, чем отправлять в туннель всё, что создаёт роутер.
Держите два правила явными, вместо того чтобы пытаться написать одно, покрывающее обе цепочки. Отдельные правила проще читать, и они позволяют отключить путь роутера, не мешая трафику клиентов во время отладки. Они также делают счётчики осмысленными по одному.
Держите собственный транспорт туннеля вне правила
Внешнее соединение туннеля тоже создаёт роутер. Правило, отправляющее весь локально созданный трафик в туннель, будет маршрутизировать туннель через себя, и он вообще не поднимется.
Административный доступ — вторая жертва. Административные сеансы, возникшие на роутере, или ответы на них, могут быть втянуты в туннель слишком широким локальным правилом и стать недоступными из LAN.
Исключите конечную точку туннеля из совпадения и держите правило ограниченным адресами резолвера. Этого достаточно для требования DNS и достаточно мало, чтобы об этом можно было рассуждать.
Проверяйте обе группы, а не одну
Понаблюдайте, как роутер делает собственный запрос, и отметьте, какой интерфейс его нёс. Повторите поиск с хоста в LAN и отметьте, каким путём он пошёл. Счётчики на правилах политики делают оба ответа видимыми без догадок.
Рассматривайте результаты как две находки. Клиент, резолвящий через туннель, ничего не говорит о роутере, а роутер, резолвящий правильно, ничего не говорит о клиенте на другом слушателе. Запишите их отдельными строками в журнале изменений.
Проверьте и порт: правило, совпадающее с портом назначения 53, пропускает резолвер, доступный через DNS over TLS на 853 или конечную точку HTTPS. Сопоставьте транспорт, который настроенный upstream действительно использует, и утечка закроется по правильной причине.