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

Начните с клиента и назовите оба конца

Начните там, где начинает пользователь, — в профиле подключения. В нём есть один удалённый адрес, один метод аутентификации и, если проект это поддерживает, список маршрутов. Обозначьте этот внешний туннель от клиента до шлюза A и дайте ему примерные адреса: адрес туннеля клиента 10.77.0.2, адрес A 10.77.0.1 и публичная конечная точка A 198.51.100.10, взятые из документационного диапазона TEST-NET-2, чтобы ничто в примере не могло столкнуться с реальным хостом.

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

Последовательно: A расшифровывает, затем снова шифрует

В последовательном варианте A завершает трафик дважды. Он снимает защиту с клиента, получает IP-пакет приложения и затем отправляет этот пакет через второй туннель, который A строит в сторону B. Между этими двумя операциями пакет лежит на пути пересылки A как обычный IP-пакет, адресованный частному назначению.

Это даёт два следствия, которые стоит сказать прямо. A может применять политику к внутреннему пакету в виде маршрутов, правил фильтрации и журналирования источника и назначения, и A должен хранить два набора учётных данных: один как сервер для клиента и один как клиент B. Защита есть в каждый момент, но защищаемый объект у A меняет идентичность.

Из этого не следует, что A читает открытый текст приложения. Когда клиент и служба используют TLS и проверяют сертификаты друг друга, A видит поток записей TLS, а не читаемый запрос. Чтобы подтвердить, где эта защита заканчивается, нужно смотреть на цепочку сертификатов службы, а не на схему туннеля.

Вложенно: A снимает только внешний слой

Во вложенном варианте клиент сначала строит внутренний туннель до B, а затем несёт этот туннель внутри внешнего до A. A снимает внешний заголовок, находит внутренний туннель и передаёт его, не держа его ключей, поэтому внутренняя защита по-прежнему заканчивается у B.

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

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

Рисуйте наблюдателей, а не только туннели

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

Vantage pointSerial chainNested chain
Client's access networkOuter tunnel onlyOuter tunnel only
Operator of AInner IP packet between A and BOuter addresses of the inner tunnel, not its payload
Path between A and BSecond tunnelSecond tunnel
Operator of BInner packet re-originated by APayload after the inner layer is removed
Service edgeTraffic from the exit addressTraffic from the exit address

Две строки постоянно путают: оператор A и поставщик туннеля клиента. Они могут быть одной сущностью, и отдельные имена шлюзов не делают их независимыми. Независимое владение требует отдельного административного контроля, отдельных учётных данных и отдельного журналирования.

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

Пройдите пути отказа, прежде чем выбирать

Ломайте вещи намеренно со стороны клиента, в том порядке, в каком пользователь с ними столкнётся. Начните с интерфейса и его MTU, потому что вложенность отказывает по размеру пакета гораздо раньше, чем по аутентификации.

ip -4 addr show dev tun0
ip link show dev tun0 | grep mtu
ping -M do -s 1380 -c 2 10.77.1.1

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

openssl s_client -connect intranet.example.com:443 -brief < /dev/null

Завершите матрицей переподключения: туннель клиента падает, туннель B падает, путь между A и B меняется. Отметьте, что возвращается, а что нет, и падает ли когда-нибудь внутреннее соединение на маршрут вне своего предполагаемого носителя. Записывайте адреса, которые использовал каждый тест, потому что повтор на другой сети доступа отвечает на другой вопрос. Повторяйте и проверку MTU после каждого переподключения, потому что изменённый путь может снизить доступный размер, не сдвинув ни одной строки конфигурации.

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

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