Намерение разумное: отправить всё для одного домена компании через туннель, а остальное оставить в покое. Редактируемая директива устанавливает маршруты, а у маршрута нет никакого понятия имени хоста, с которым можно сопоставиться. Любая попытка записать в неё wildcard даёт либо ошибку разбора, либо, что хуже, маршрут, который сегодня случайно работает, потому что имя разрешилось в один адрес. Два разных механизма просят делать работу друг друга.

Что устанавливает маршрут и чего он никогда не читает

Запись маршрута говорит, что префикс назначения доступен через интерфейс. Ядро сопоставляет пакеты с этими префиксами, поэтому единственные участвующие идентификаторы — адреса и маски. Имя хоста никогда не появляется в решении о пересылке, и именно поэтому шаблон там сопоставить нельзя.

OpenVPN может принимать разрешимое имя в некоторых параметрах маршрута, и эта терпимость — источник путаницы. Имя разрешается при применении конфигурации, порождая один или несколько адресов, которые становятся обычными маршрутами. После этого имя полностью исчезает с картины.

Итак, маршрут, построенный из имени, — это снимок, а не правило. Он покрывает то, во что это имя разрешилось в момент запуска туннеля, и это именно то поведение, которого вы не хотите для меняющегося семейства хостов. Запись, которая переедет завтра, оставляет маршрут указывающим на вчера.

Когда пункт назначения действительно является префиксом

Если цель — известная частная сеть, напишите префикс. Для примера из пространства документации один хост и одна подсеть выглядят так:

route 10.60.4.20 255.255.255.255
route 10.60.0.0 255.255.0.0

Обе записи называют адреса и маски, и обе переживают изменения DNS, потому что ничто в них не зависит от имени. В этом всё преимущество: маршрут — это утверждение о топологии, а не о поиске, который произошёл однажды.

Не выводите большой префикс из одного ответа DNS. Одно имя хоста, разрешившееся в один адрес, ничего не говорит о размере сети за ним, и именно угаданный префикс приводит к тому, что туннель начинает захватывать трафик, который никто не собирался через него отправлять. Спросите владельца сети о фактическом префиксе, вместо того чтобы выводить его из поиска.

Когда единица работы — имя хоста

Выбор по домену требует чего-то, что читает домен, то есть компонента прикладного уровня. Обычный ответ — HTTP-прокси, который находится на другой стороне туннеля, а клиент выбирает, какие запросы ему отправлять.

Файл конфигурации прокси может выразить этот выбор. Показательные правила ниже отправляют один домен и его поддомены в прокси, а всё остальное напрямую:

function FindProxyForURL(url, host) {
    var h = host.toLowerCase();
    if (h === "corp.example" || dnsDomainIs(h, ".corp.example")) {
        return "PROXY 10.60.0.12:3128";
    }
    return "DIRECT";
}

Сравнение точного имени охватывает сам домен, а сравнение суффикса охватывает его потомков, не совпадая с именем, которое просто заканчивается похожими символами. Нужны оба, и пропуск одного даёт правило, которое выглядит правильным и пропускает вершину или самозванца.

Эти правила выбирают прокси; они не создают его и не меняют ни одного маршрута операционной системы. Адресу прокси по-прежнему нужен собственный путь через туннель, а запросы, помеченные как прямые, следуют той политике маршрутизации, которая уже есть у машины.

Чего не покрывает опция прокси

Программы, которые игнорируют конфигурацию прокси браузера, не пострадают ни от чего из этого. Инструменты командной строки, программы обновления и приложения с собственным сетевым стеком берут таблицу маршрутов, а не PAC-файл, поэтому таким случаям нужен поддерживаемый механизм для отдельного приложения или другой дизайн. Составьте список важных клиентов, прежде чем обещать, что правило браузера покрывает рабочий процесс.

Возврат напрямую — тоже не выход. Если политика маршрутизации машины уже отправляет всё в туннель, запрос, помеченный как прямой, остаётся внутри, потому что выбор прокси и таблица маршрутов — разные решения, принимаемые на разных уровнях.

Разрешение имён — третий отдельный вопрос. Выбор того, какие запросы идут в прокси, ничего не говорит о том, какой резолвер на них отвечает, а отношение к обоим как к одной настройке порождает утечки, которые невидимы, пока кто-то не проверит снаружи. Решите, где отвечают на каждый запрос, и запишите это решение рядом с правилом прокси. Резолвер, который меняется из-за поднятия туннеля, тихо сдвинет ответ.

Проверять оба пути, а не только удачный

Проверьте имя хоста, которое должно совпасть, имя хоста, которое не должно, и вершину домена, поскольку вершина — это случай, который чаще всего пропускается правилом только с суффиксом. Затем подтвердите, каким путём на самом деле прошёл каждый запрос, вместо того чтобы выводить это из того, загрузилась ли страница.

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

Похожие статьи