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

Три вопроса перед любой командой

Первое: есть ли запись для локального префикса и указывает ли она на физический адаптер? Второе: получает ли клиент при подключении разрешение или запрет локальной сети от шлюза? Третье: нужен ли вам только исходящий доступ к локальной сети, или что-то в интернете тоже должно доходить до службы, работающей на вашей машине?

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

What you seeWhat it points at
No local prefix in the tableMissing route
Correct prefix, no replyClient filter or gateway policy
Works by IP, fails by nameResolver changed by the tunnel
Inbound service dies, outbound fineReturn path or listener binding

Вопрос первый: маршрут, фильтр или имя

Прочитайте таблицу, прежде чем что-либо в неё добавлять. Индекс интерфейса важен, потому что каждая команда маршрута ниже привязана к нему:

route print -4
Get-NetRoute -DestinationPrefix 192.168.1.0/24 | Format-Table InterfaceIndex,NextHop,RouteMetric

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

Проверяйте отдельно по адресу и по имени. Если ping 192.168.1.50 отвечает, а net view 192.168.1.50 нет, таблица маршрутизации никогда не была проблемой: туннель сменил резолвер, и локальное имя больше не разрешается. Добавлять для этого маршрут — пустая работа.

Вопрос второй: разрешает ли шлюз доступ к локальной сети?

Коммерческий клиент устанавливает больше, чем маршруты. При подключении он получает политику, и эта политика может включать явное разрешение локальной сети. В развёртываниях Cisco IPsec групповая политика несёт настройку раздельного туннелирования и отдельный флаг доступа к локальной сети; флажок в клиенте — это запрос, который шлюз может отклонить. В AnyConnect профиль управляет списками включения и исключения разделения и тем же разрешением. В Windows RRAS эквивалентами являются параметр шлюза по умолчанию в профиле плюс статические маршруты, которые назначает сервер.

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

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

Вопрос третий: какое направление вам нужно?

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

route add 192.168.1.0 mask 255.255.255.0 192.168.1.1 metric 1 if 12
route add 192.168.1.50 mask 255.255.255.255 192.168.1.1 -p

Вторая форма закрепляет одно устройство, и это то, что нужно, когда один адрес — всё требование. Эквивалент netsh записывает то же решение по имени интерфейса, а не по индексу:

netsh interface ipv4 add route prefix=192.168.1.0/24 interface=12 nexthop=192.168.1.1 store=persistent

Команды маршрута завершаются ошибкой Параметр задан неверно, когда адрес и маска не согласуются, например адрес хоста с маской /24. Для маршрута подсети используйте адрес сети, а для одного хоста — маску хоста.

Входящий трафик отличается. Сервер VNC или SSH на той же машине становится недоступным, когда ответы на входящее соединение уходят через шлюз VPN и никогда не возвращаются. Проверьте, что слушает служба, прежде чем трогать маршруты:

netstat -ano | findstr :5900

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

Примените наименьшее подходящее изменение

Другое распространённое действие — снять флажок «Использовать шлюз по умолчанию в удалённой сети» в дополнительных свойствах IPv4. Это оставляет интернет-трафик локальным, но делает две вещи сразу: VPN перестаёт быть путём по умолчанию, и клиент перестаёт получать маршруты для удалённой сети, включая multicast. Снимите флажок, и удалённая сеть исчезнет, если только сервер не проталкивает конкретные удалённые префиксы, нужные каждому клиенту.

Эта асимметрия определяет порядок работы. Если удалённая сторона должна оставаться полностью доступной, проталкивайте удалённые подсети с сервера и не трогайте локальный маршрут по умолчанию. Если сервер изменить нельзя, добавьте постоянный маршрут к удалённому префиксу через адрес, который выдал туннель, и проверьте с помощью route print, что префикс указывает на интерфейс VPN, а маршрут по умолчанию по-прежнему указывает на физический шлюз.

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

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