Разделённый DNS и VPN: правила доменов — не IP-маршруты
Разделённый DNS выбирает резолвер по имени, а ответу всё ещё нужен маршрут. Проверяйте правило домена и путь отдельно, на платформе, которую вы действительно используете.
Ваш ноутбук разрешает intranet.corp через туннель, а gitlab.com продолжает идти к резолверу провайдера, и это та схема, которая работает как задумано. Её создали два отдельных решения: правило сопоставления имён выбрало резолвер, а маршрут вернул ответ. Сломайте любое из них, и браузер покажет сбой, который снаружи выглядит одинаково. Большинство отчётов о разделённом DNS описывают второй сбой, цитируя при этом доказательства о первом.
Две половины живут в разных местах и обычно редактируются разными людьми. Одна — это политика DNS, привязанная к профилю VPN, другая — маршрут, который туннель устанавливает или удерживает. Отладка останавливается, когда никто не установит, какая половина на самом деле сдвинулась.
Два решения, скрытые в одном запросе
Половина имени — это объект политики, а не маршрут. В Windows это политика разрешения имён в профиле VPN; на платформах Apple набор совпадающих доменов в объекте настроек DNS; в Linux домен маршрутизации, строка разделённого резолвера или порядок переключателя служб имён. Половина пути — это обычная маршрутизация, установленная туннелем или вручную, и она понятия не имеет, что такое имя хоста. Профиль, допускающий суффикс, решает только, кто отвечает; он никогда не делает ответ достижимым.
Быстрый тест симптомов разделяет их: замените имя адресом. Если адрес работает, путь в порядке, а правило неверно. Если адрес тоже не работает, правило может быть верным, а путь — отсутствовать.
Как каждая платформа выражает одно и то же правило имён
Замысел одинаков, а названия полей — нет. Пример, скопированный из одного клиента в другой, разбирается чисто и никогда не совпадает. Три формы выглядят так:
| Platform | Where the rule lives | What usually breaks |
|---|---|---|
| Windows | name-resolution policy on the VPN profile | precedence against the interface suffix list |
| Apple platforms | match domains on the DNS settings object | domains attached to the wrong extension |
| Linux | routing domain, split resolver, nsswitch order | the suffix written the wrong way round |
Домен совпадения или маршрутизации — это проверка суффикса, поэтому intranet.corp покрывает git.intranet.corp и не покрывает corp.intranet, и перевернуть это — самая частая ошибка во всей настройке. Windows несёт сопоставление как политику разрешения имён, привязанную к профилю, со своим порядком приоритета по отношению к любому списку суффиксов, который уже был у интерфейса. Платформы Apple привязывают совпадающие домены к объекту настроек DNS сетевого расширения, и система применяет их для каждого ограниченного резолвера. Ни одна из этих форм не является маршрутом, и ни одна не может сделать недостижимый адрес достижимым. Справочник политика разрешения имён Windows перечисляет названия полей и правила приоритета для этой платформы, и они не те, что используют документы Apple или systemd.
Правильному ответу всё ещё нужен путь
Ответ резолвера — это только адрес, и приложению всё ещё нужно до него добраться. Схема разделённого туннеля часто продвигает 10.20.0.0/16 и удерживает маршрут по умолчанию, поэтому внутреннее имя разрешается, а соединение затем зависает. Обратный случай столь же част: маршрут есть, публичный резолвер отвечает на частное имя NXDOMAIN, и сбой записывается как проблема маршрутизации. Проверка пути первым заставляет вас смотреть на маршруты для имени, которое никогда бы не разрешилось.
Есть и третьи ворота, которые не покрывает ни одна половина. ACL на шлюзе, правило брандмауэра или политика на стороне клиента могут сбросить соединение после того, как оба решения были верны. Когда имя разрешается, маршрут есть, а соединение всё равно истекает по тайм-ауту, прекратите проверять DNS.
Проверка имён и путей в фиксированном порядке
Выберите порядок и держитесь его, иначе будете гоняться за шагом, который не удался последним. Разрешите задокументированное полное внутреннее имя, убедитесь, что ответ — адрес, который может нести таблица маршрутизации, затем повторите с публичным именем, чтобы доказать, что туннель не захватил всё. На хосте systemd запрос и домен маршрутизации резолвера отстоят на одну команду:
resolvectl query intranet.corp
resolvectl domain
ip route get 10.20.5.10
Клиент Windows задаёт те же два вопроса другими командлетами. Второй сообщает интерфейс, который система действительно использовала бы:
Resolve-DnsName intranet.corp -Type A
Find-NetRoute -RemoteIPAddress 10.20.5.10
Если поиск возвращает адрес, а проверка пути называет физический интерфейс, правило имени сработало, а маршрут нет. Если короткое имя не работает, а полное разрешается, неверен список суффиксов, а не резолвер.
Где сравнение обычно идёт не так
Первая ошибка — спрашивать несвязанный публичный резолвер о частном имени и читать отказ как доказательство о VPN. Вторая — предполагать, что работающий публичный поиск доказывает путь резолвера туннеля. Третья — рассматривать раздельное туннелирование и разделённый DNS как одно проектное решение, тогда как развёртывание может быть верным в одном и сломанным в другом. Каждая ошибка даёт уверенные выводы из теста, который ни разу не задействовал обвиняемую часть.
Браузер с собственным безопасным DNS тоже может обойти системное правило, поэтому то, что один браузер терпит неудачу, а другой успешно работает, не противоречие. Сравнивайте резолвер, который ответил, а не браузер, который пожаловался.
Когда обе половины видны, оставшийся вопрос — вопрос политики, а не техники: какие пространства имён принадлежат организации, кто владеет каждым ответом и какие из них вообще должны покинуть машину. Запишите это рядом с профилем, потому что следующему человеку, который тронет правило, это понадобится.