Представьте браузер, загружающий страницу HTTPS, пока SSH-клиент достигает другого сервера, а резолвер отвечает на запрос, — всё через один сеанс OpenVPN. На физическом интерфейсе вы видите один разговор; внутри туннеля — три. Оба взгляда верны, и знание почему — это разница между полезной и путаной записью. Проследите один внутренний поток от сокета до провода, и многослойность перестаёт быть абстракцией.

Один внешний разговор, много внутренних потоков

Каждое приложение открывает свой сокет, и ядро выдаёт ему кортеж из пяти элементов: адрес источника, порт источника, адрес назначения, порт назначения и протокол. Эти кортежи существуют ещё до того, как в дело вступает какой-либо туннель. Затем маршрутизация решает, что все они выходят через туннельное устройство, поэтому пакет, переданный OpenVPN, по-прежнему несёт внутри исходные заголовки. OpenVPN шифрует этот внутренний пакет и заворачивает результат в один внешний разговор UDP или TCP с партнёром. Значит, внешний разговор один, а потоков внутри столько, сколько открыли приложения.

Ничего не сворачивается. Внутренние кортежи сохраняются от конца до конца, и именно поэтому удалённая сторона по-прежнему различает три потока.

Порт, который остаётся неизменным

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

Внутренние порты — это то, что важно конечным точкам. Поток HTTPS сохраняет порт назначения 443 внутри туннеля, хотя внешний транспорт сидит на том порте, который настроил оператор. Конечные точки приложения никогда не узнают о внешнем.

Что декапсуляция меняет на дальнем конце

У партнёра внешний слой снимается, и остаётся внутренний пакет. Оттуда пересылка и политика доступа применяются к внутреннему назначению и протоколу. Веб-сервер по-прежнему получает соединение HTTPS, демон SSH по-прежнему получает SSH, а резолвер по-прежнему получает запрос.

Поэтому правило, разрешающее внешний транспорт, — не то же правило, что разрешение внутренней службы. Первое описывает путь; второе описывает авторизацию.

Внешний TCP означает один поток, а не одно соединение

Когда внешний транспорт — UDP, судьба каждого внутреннего потока независима: потерянная датаграмма влияет на одну передачу до её собственной повторной отправки. Когда внешний транспорт — TCP, все внутренние потоки делят один надёжный поток байтов.

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

Опишите свою конфигурацию точно

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

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

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