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

Три условия решают вложенность

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

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

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

Условие первое: какая конечная точка нуждается в каком пути

ip route get 203.0.113.10 отвечает на этот вопрос напрямую: команда печатает маршрут, адрес источника и интерфейс, который ядро использовало бы для этого назначения прямо сейчас.

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

Условие второе: проверьте путь на каждом уровне

Выбор маршрута на современном клиенте — это больше, чем главная таблица. Правила политики могут отправлять помеченные пакеты в другую таблицу, клиент может привязать свой сокет к интерфейсу, а контейнер или пространство имён имеет собственные таблицы. ip rule и ip route show table all — это способ узнать, какой из этих механизмов задействован.

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

Условие третье: что происходит, когда внешний туннель падает

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

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

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

Чего цепочка не даёт

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

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

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