Почему хост в локальной сети отправляет ARP для адреса клиента OpenVPN
Пул клиентов внутри префикса локальной сети заставляет локальную сеть отправлять ARP для адреса, до которого она не может добраться. Прочитайте префикс, проследите решение о прямой связи и затем перенесите пул.
Проблемы доступности между хостом в локальной сети и клиентом VPN часто восходят к самому плану адресации. Дайте этому хосту интерфейс на 10.0.100.0/22, и он будет считать каждый адрес от 10.0.100.0 до 10.0.103.255 подключённым напрямую, включая пул клиентов, тихо размещённый на 10.0.101.0/24. Ответ никогда не уходит на маршрутизатор, потому что с точки зрения хоста маршрутизатор не участвует. Пакет адресован соседу и запрашивается по проводу.
Этот механизм стоит за целым семейством сообщений: туннель поднят, у сервера есть маршрут, а хост в локальной сети по-прежнему не может достучаться до клиента.
Префикс /22, который поглощает /24
Читайте префикс как диапазон, а не как строку. Префикс /22 содержит 1024 адреса, а 10.0.100.0/22 простирается от 10.0.100.0 до 10.0.103.255, поэтому пул на 10.0.101.0/24 целиком лежит внутри. Ошибка переживает проверку потому, что первые октеты пула выглядят иначе, чем первые октеты локальной сети, и только третий октет выдаёт вложенность. Запишите оба диапазона в числах, прежде чем объявлять их раздельными.
Та же вложенность может проявиться и в обратную сторону. Пул, который выглядит свободным, потому что сейчас его никто не использует, всё равно может попасть в префикс, анонсированный каким-нибудь маршрутизатором площадки, и план адресации — единственный документ, который это показывает.
Прямая связь означает ARP, а не маршрутизацию
Когда хост с интерфейсом /22 отправляет пакет на 10.0.101.25, ядро сравнивает получателя с префиксом интерфейса и находит совпадение. Пакет становится поиском соседа, а не маршрутизируемым пакетом, а в Ethernet поиск соседа — это ARP-запрос для этого адреса. Если адрес принадлежит клиенту VPN за маршрутизируемым шлюзом, ни один хост в локальной сети им не владеет, поэтому запрос остаётся без ответа, а пакеты отбрасываются. Туннель не виноват, и клиент никогда не видит трафик.
Поэтому сбой выглядит асимметричным и иногда прерывистым. Хост VPN часто достаёт локальную сеть, потому что его собственные маршруты указывают в нужную сторону, тогда как хост в локальной сети не может ответить, и любое кеширование устаревшей записи ARP заставляет симптом мерцать.
TUN, TAP и что несёт каждый
Устройство TUN переносит IP-пакеты, а устройство TAP переносит кадры Ethernet. Маршрутизируемое соединение TUN не обязано переносить ARP, чтобы обеспечить доступность IP, и именно поэтому запрос без ответа выше ожидаем, а не сломан. TAP с намеренно настроенным мостом может расширить широковещательный домен и заставить ARP работать, но это меняет то, что видит клиент, требует конечных точек с той же инкапсуляцией и является переделкой сетевой модели, а не починкой перекрывающегося префикса. Переход с маршрутизируемого развёртывания на TAP ради исправления ошибки плана адресации меняет маленькую проблему на большую.
Запишите, где появился ARP-запрос и какая система его отправила, прежде чем делать выводы. Отправитель сообщает вам, что он думает о получателе, а не что делает туннель.
Спроектируйте пул, который не может пересекаться
Выберите пул вне каждого подключённого префикса и каждого анонсированного префикса площадки, затем добавьте маршруты, которые делают его достижимым в обе стороны. Диапазон вроде 10.8.0.0/24 в неиспользуемой части плана легко обдумать, а локальная сеть, которой нужно до него добраться, получает статический маршрут, указывающий на сервер VPN. Меняйте вместе выделение, анонсируемые маршруты, разрешённые адреса источников и правила брандмауэра, потому что они описывают один проект, а не четыре настройки.
Source NAT на сервере может скрыть пул за адресом, маршрутизируемым из локальной сети, и это законный инструмент миграции. Он также переписывает источник, поэтому локальная сеть теряет возможность относить соединения к отдельным клиентам и применять правила для клиента.
Для приёмки используйте реально выданный адрес настоящего клиента и реальный запрос приложения с хоста в локальной сети, затем подтвердите, что ответ идёт через запланированный шлюз, а не по проводу.