Пинги на туннельный адрес сервера проходят, собственная таблица маршрутов клиента выглядит правильно, а LAN за этим клиентом по-прежнему недоступна. Таблица маршрутизации клиента выглядит корректно, у сервера есть маршрут в туннель, а пакеты всё равно исчезают. Это классический симптом туннеля layer-3, который не знает, что один из его клиентов сам является шлюзом.

У интерфейса tun нет следующего перехода для каждого клиента. Ядро видит один интерфейс со множеством партнёров, поэтому решение о том, какой клиент должен получить пакет для удалённой LAN, принимается внутри процесса OpenVPN. Это решение настраивается через iroute, и без него пакету некуда идти.

Сервер маршрутизирует по клиенту, а не по интерфейсу

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

OpenVPN решает это внутренней таблицей маршрутизации, которая сопоставляет префикс назначения конкретному клиенту. Эта таблица строится из записей iroute, поэтому обычного маршрута на хосте сервера недостаточно. Маршрут ядра доставляет пакет к интерфейсу туннеля; внутреннее сопоставление решает, какой сеанс его получит. Поэтому исправление никогда не появляется в выводе маршрутов ядра.

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

Записать запись iroute, которая называет клиента

iroute живёт в конфигурационном файле конкретного клиента, а не в основной конфигурации сервера. Укажите серверу каталог опцией client-config-dir, затем создайте файл, имя которого совпадает с общим именем сертификата клиента, и поместите в него префикс.

Для филиала, чья LAN — 10.20.0.0/24, а общее имя сертификата — branch-router, файл по этому пути содержит строку вроде iroute 10.20.0.0 255.255.255.0. Основной конфигурации нужна только опция каталога; префикс живёт у клиента.

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

Один клиент может владеть несколькими префиксами. Добавьте по одной строке iroute на каждую сеть и держите список рядом с остальными настройками этого клиента, чтобы сопоставление оставалось проверяемым.

Построение обратного пути в обоих направлениях

Доставка пакетов в удалённую LAN — половина работы. Клиент также должен отправлять трафик этой LAN в туннель, что обычно делается проталкиванием маршрута клиенту: строка вроде push "route 10.8.0.0 255.255.255.0" сообщает каждому клиенту, как добраться до сети на стороне сервера. Для филиала эквивалентный маршрут указывает в туннель для всего, чего он должен достичь на стороне сервера.

Обратному направлению нужен владелец на дальней стороне. Там кто-то должен знать путь назад: статический маршрут на маршрутизаторе LAN, направляющий пул VPN на сервер, или трансляция адресов на сервере до того, как трафик войдёт в LAN. Статический маршрут сохраняет исходные адреса видимыми в журналах и правилах доступа, но требует сотрудничества владельца LAN; трансляция самодостаточна, но скрывает, кто на самом деле подключился.

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

Проверка доступности правильными пробами

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

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

Два сервера, соединённые туннелем, повторяют одно и то же правило с обеих сторон: каждому нужна iroute для пула другого, и каждому нужны маршрут и пересылка, делающие путь симметричным. Маршрутизация и политика здесь — разные вещи. Маршрутизация решает, куда пакет может идти, а правило FORWARD решает, разрешено ли, поэтому клиент с двумя строками iroute достигает обоих префиксов, если фильтр не говорит иначе.

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