Исключение одного узла из маршрута по умолчанию Windows VPN
Профиль полного туннеля владеет маршрутом по умолчанию. Одному узлу нужен более узкий префикс на физическом интерфейсе, который добавляется заново после каждого подключения.
Ноутбук подключается к офисному VPN, и всё идёт за ним, включая веб-страницу принтера и одну интрасеть, которая отвечает только в локальной сети. Сделанный вручную маршрут исправляет это на час, потом соединение обрывается, возвращается, а исключение исчезает. С туннелем всё в порядке: Windows держит одну таблицу маршрутизации, и адаптер VPN при каждом подключении перезаписывает свою долю в этой таблице. Выживает только то, что живёт вне собственных записей адаптера.
Какую запись забирает туннель
Запишите таблицу дважды, один раз с выключенным туннелем и другой раз с включённым, и сравните строки по умолчанию. Когда профиль требует префикс по умолчанию, запись адаптера самая широкая строка в таблице, поэтому любое исключение должно быть уже её. Это арифметика длины префикса, а не утверждение о доверии или политике. Она же определяет, какой интерфейс должно назвать исключение.
Запишите индекс интерфейса и локальный шлюз, прежде чем идти дальше, потому что оба меняются, когда машина подключается к другой сети. Команды ниже читают их с машины, а не из памяти.
route print -4
Find-NetRoute -RemoteIPAddress 198.51.100.30
Вторая команда сообщает интерфейс и следующий переход, которые этот единственный адрес использовал бы прямо сейчас, что лучше, чем читать сорок строк и гадать. Запустите её до и после подключения, и у вас будет пара, которую стоит приложить к записи об изменении. Оба вывода дают числа, используемые в остальной части этой страницы.
Маршрут к узлу побеждает по точности
Совпадение самого длинного префикса решает, кто победит, поэтому /32 через физический шлюз побеждает маршрут по умолчанию через туннель, не затрагивая туннель. Трафик к этому адресу выходит через локальный интерфейс, а всё остальное сохраняет текущий путь. Туннель по-прежнему несёт маршрут по умолчанию и просто перестаёт быть единственным кандидатом для этого назначения. Длина префикса единственный рычаг, который даёт таблица, и для этой задачи его достаточно.
Точность также исключает очевидный обходной путь исключить доменное имя, потому что таблица сопоставляет адреса, а одно имя может разрешаться в несколько. Сначала разрешите узел, затем решите, какой из его адресов заслуживает исключения.
Для всего ниже предположим подключение с именем Office, локальный шлюз 10.0.0.1 на интерфейсе 7 и назначение 198.51.100.30. Это заполнители, а не значения по умолчанию, и команды выше дают значения, которые ваша машина действительно использует. Сохраните эту заметку о подстановке вместе с изменением, чтобы следующий читатель не скопировал числа.
Сделайте так, чтобы маршрут пережил следующее переподключение
Windows не предлагает никакой инструкции исключения для подключения VPN, поэтому исключение должно жить на физическом интерфейсе, где адаптер его не перезапишет. Командлет, который выглядит как ответ, делает обратное: Add-VpnConnectionRoute переносит префикс в туннель, а это зеркальный случай, когда разделённый профиль должен нести одно назначение, а остальное оставить локальным. Обращение к нему здесь гарантирует, что трафик, который вы хотели оставить снаружи, пойдёт внутрь.
Ручная форма одна команда. Её слабость в смене сети, а не в переподключении.
route -p add 198.51.100.30 mask 255.255.255.255 10.0.0.1 metric 1 if 7
Это переживает перезагрузку благодаря -p и отправляет один адрес через интерфейс 7, пока туннель несёт всё остальное. Перенесите ноутбук в другую сеть, и шлюз с индексом устареют, поэтому запись тихо перестанет работать. Запишите, кому она принадлежит и когда её нужно удалить.
Скрипт подключения более надёжный вариант, потому что он добавляет исключение заново после каждого подключения вместо надежды на то, что запись выжила. Две строки ниже относятся к тому, что поднимает туннель, а не к скрипту входа.
rasdial Office
route add 198.51.100.30 mask 255.255.255.255 10.0.0.1 metric 1 if 7
Что бы ни поднимало туннель, это правильное место для второй строки, и rasdial возвращается только после установления соединения, поэтому маршрут оказывается позади собственных записей адаптера. Запустите его снова после пробуждения, потому что приостановка может сбросить маршрут и оставить туннель поднятым. Если задача обратная, протолкнуть один префикс в туннель, а остальное оставить локальным, тогда Add-VpnConnectionRoute и есть правильный инструмент.
Маршрутизация не может выбрать процесс
Иногда требование уже назначения: одна программа должна идти локальным путём, а всё остальное оставаться внутри туннеля. Маршрутизация не может это выразить, потому что сопоставляет адреса, а не процессы. Рабочий шаблон сваливает проблему на запускающую оболочку.
Держите профиль вне маршрута по умолчанию и запускайте ту единственную программу привязанной к адресу локального интерфейса, тогда исключением становится команда запуска, а туннель сохраняет то, что уже обрабатывал. В таблице маршрутизации ничего не меняется, и именно поэтому это переживает переподключения. Это также значит, что туннель не должен владеть маршрутом по умолчанию изначально, так что это другая конструкция, а не заплатка на предыдущую.
Её слабость операционная, а не техническая. Программа должна всегда запускаться через обёртку, и если после пробуждения привязки нет, она тихо выберет любой путь, который предложит таблица. Это терпимо для браузера, который вы открываете намеренно, и неприемлемо для всего, что никогда не должно покидать туннель.
Подключения для отдельных пользователей тоже этого не решают. Windows может ограничить подключение учётной записью, но таблица маршрутизации остаётся общей для машины, поэтому подключение, привязанное к учётной записи и держащее маршрут по умолчанию, всё равно перенаправляет каждый процесс на машине, включая другие сеансы. Область становится реальной только тогда, когда область маршрута совпадает с учётной записью. Поэтому два человека, делящие один ноутбук, делят одну таблицу, и второй наследует тот туннель, который запустил первый.
Убедитесь, что исключение пережило переподключение
Проверьте изменение так, как оно сломается: отключитесь, подключитесь заново, откройте новое приложение, затем запросите один адрес, который должен остаться локальным, и один, который должен идти через туннель. Сравните оба с Find-NetRoute в подключённом состоянии.
Если после переподключения префикса нет в таблице, он живёт в неправильном объекте, а не в неправильном формате. Перенесите его на физический интерфейс и повторите тест. Сохраните оба вывода команд вместе с записью об изменении, потому что снимок работающего состояния позже отвечает на больше вопросов, чем абзац объяснения. Следующему человеку захочется узнать, что дало подключение, а не что вы собирались получить.