Новый VPN-протокол TrustTunnel спасет нас

vaspvort

Ночной дозор
Команда форума
Модератор
ПРОВЕРЕННЫЙ ПРОДАВЕЦ
Private Club
Migalki Club
Старожил
Меценат💎
Регистрация
10/4/18
Сообщения
7.093
Репутация
12.129
Реакции
19.157
USDT
0
Сделок через гаранта
18
На днях AdGuard выложил в открытый доступ свой VPN-протокол, который назвал TrustTunnel. В статье разберемся, чем он отличается от того же VLESS и как устроен на самом деле.

d44c0df8aa62c0c2cd43243dfe5a8f56.png

Проблема любых VPN-протоколов​

AdGuard в своем анонсе заявляют, что любой VPN-протокол - это компромисс. Он либо быстрый, но легко детектится (WireGuard, OpenVPN, etc.), либо маскируется под обычный трафик, но тормозит.

Главная проблема тормозов в классическом подходе «устойчивых» протоколов - они обертывают VPN-данные в TCP-соединение и мимикрируют под HTTPS. Выглядит это в итоге как обычный веб-трафик, но TCP добавляет проблем со своим обязательным подтверждением доставки пакетов. При таком подходе, при потере одного пакета встаёт вся очередь пакетов, что приводит к классическому head-of-line blocking, жутко замедляя соединение.

Как это работает в VLESS​

VLESS (V2Ray/Xray) - популярный выбор для обхода блокировок. Протокол лёгкий, имеет минимумом фич, которые бы его замедляли и умеет маскироваться под HTTPS через TLS.

Но есть у него и нюанс - VLESS работает поверх TCP. Конечно можно использовать WebSocket, gRPC или QUIC как транспорт, но всё же для упрощения возьмем базовую схему - это TCP-обёртка со всеми вытекающими.

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

Как это хочет решить TrustTunnel?​

На официальном сайте компании написано:

"Unlike traditional VPNs that operate on packets, TrustTunnel operates on data streams. This design enables packet buffering — multiple packets can be combined before transmission, dramatically reducing confirmation overhead"
Звучит так, будто они объединяют несколько VPN-пакетов в один блок и так экономят на ACK'ах (подтверждениях доставки). Грубо говоря так и есть, но с небольшими оговорками.

Как реализовали​

Смотрим PROTOCOL.md:

Для TCP-соединения каждое туннелируемое TCP-соединение получает отдельный HTTP stream через стандартный метод CONNECT:

CONNECT example.com:443 HTTP/2
:method: CONNECT
:authority: example.com:443
proxy-authorization: Basic <credentials>


После ответа 200 OK протокол начинает общение по HTTP/2 стримингу двунаправленным байтовым потоком. Данные просто текут туда-сюда, не дожидаясь ACKов.

В UDP-трафике все поинтереснее: вся UDP-дата мультиплексируется в один HTTP stream (_udp2). Каждый пакет оборачивается в структуру:

[Length 4B][Src IP 16B][Src Port 2B][Dst IP 16B][Dst Port 2B][App Name Len 1B][App Name][Payload]


Аналогично для ICMP - один stream _icmp для всех пингов.

Таким образом, трафик, проходящий через туннель, смешивается с обычным легитимным, ведь по сути им и является. И, опять же, в отличии от обычных «оберток», по умолчанию оборачивает все в streamы.

А где буферизация-то?​

В спецификации протокола нет собственного механизма буферизации. TrustTunnel не оверинжинирит, а использует буферизацию, в которую уже умеют HTTP streamы.

┌─────────────────────────────────────────────────────────┐
│ TrustTunnel │
│ (любая дата, передаваемая через туннель) │
└────────────────────────┬────────────────────────────────┘
│ write()

┌─────────────────────────────────────────────────────────┐
│ HTTP/2 (h2) / HTTP/3 (quinn) стрим │
│ flow control window в 131072 байт │
│ Собирается фрейм с max_frame_size до 16384 байт │
└────────────────────────┬────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ TLS / QUIC │
│ + Записывают несколько запросов в один │
│ + Свои буферы отправки │
└────────────────────────┬────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│ TCP / UDP │
└─────────────────────────────────────────────────────────┘


Конфигурационные параметры​

В CONFIGURATION.md описаны параметры, влияющие на агрегацию:

Параметр​
Значение по умолчанию​
Описание​
max_frame_size​
16384 байт​
Максимальный размер HTTP/2 фрейма​
recv_udp_payload_size​
1350 байт​
Размер UDP-датаграммы для QUIC​
send_udp_payload_size​
1350 байт​
Размер исходящих UDP-пакетов​
header_table_size​
65536 байт​
Таблица сжатия HPACK​
initial_stream_window_size​
131072 байт​
Окно flow control​

И сколько пакетов влезает в один фрейм?​

Окей, возьмем значения по умолчанию.
Раз max_frame_size = 16384 байт, можно посчитать:

HTTP/2 со стандартными пакетами (~1400 байт MTU):

16384 / 1400 ≈ 11 пакетов на фрейм


HTTP/2 с мелкими пакетами (VoIP, ~200 байт):

16384 / 200 ≈ 81 пакет теоретически


(Но на практике VoIP-пакеты не буферизируются так агрессивно из-за требований к latency - отправляются по 1-3 штуки)

QUIC с крупными пакетами:

1350 / 1400 < 1 — нужна фрагментация


QUIC с мелкими пакетами:

1350 / 200 ≈ 6-7 пакетов


Динамический батчинг​

Тут важно понимать: такой расчет типа «сколько пакетов отправится за раз» - это то, сколько может быть отправлено их максимально в одном фрейме. На деле же это динамическая величина.

TrustTunnel написан на Rust с асинхронным Tokio. По сути, всю софтварную задержку этим убрали:

  1. Нет блокирующего потока, который «сидит и ждёт» N пакетов
  2. Все данные сразу копируются в буфер библиотеки h2/quinn
  3. Сама библиотека решает, когда делать flush и отправлять данные в фрейме
  4. При медленной же сети TCP-буфер заполняется, а пакеты накапливаются в RAM. Когда сеть освобождается, TrustTunnel может отправить сразу серию фреймов
В конфиге max_frame_size (что очевидно из названия, такто!) задаёт верхний предел одного фрейма данных, а не фиксированный размер батча.

Выводы и сравнения​

Просуммируем весь кайф протокола, который уменьшает его задержку еще раз:

  1. Мультиплексирует много TCP-соединений в одну TLS-сессию. Не надо делать отдельный TLS handshake на каждое соединение.
  2. Поддержка QUIC (HTTP/3) при использовании QUIC получаем отсутствие head-of-line blocking. Потеря пакета в одном stream не блокирует другие.
  3. То, за что изначально боролась компания - энергоэффективность на мобильных устройствах - агрегация в HTTP стримы позволяет LTE-модему передавать данные одним разом и быстрее уйти в режим пониженного энергопотребления, вместо того чтобы посылать по одному пакету и не давать продыху.
  4. И при всем этом он идеально маскируется под HTTPS: ведь буквально весь трафик выглядит как обычные CONNECT-запросы. DPI видит стандартный HTTP/2 over TLS.
И всё это теперь открыто под лицензией Apache 2.0 - можно форкать и использовать. Красота.

Сравнение с VLESS​

VLESS + TCP/TLS​
TrustTunnel​
Маскировка​
Похож на HTTPS​
Стандартный HTTP/2 CONNECT​
Транспорт​
TCP (+ WS/gRPC/QUIC)​
HTTP/2 или QUIC​
TCP-туннели​
Своя реализация​
HTTP CONNECT per connection​
UDP​
Своя реализация (XUDP)​
Мультиплекс через один stream​
Head-of-line blocking​
Есть (на TCP)​
Нет (при QUIC)​
Шифрование​
Внешнее TLS​
TLS 1.2+ обязателен​
Макс. размер батча​
Зависит от транспорта​
16384 байт (HTTP/2) / 1350 байт (QUIC)​
Буферизация​
Своя или транспорта​
Полностью на уровне HTTP/2/QUIC​

Таймауты по умолчанию​

  • Connection timeout: 30 сек
  • Health check: 7 сек
  • TCP idle: 2 часа
  • UDP idle: 120 сек
TrustTunnel - это HTTP/2 CONNECT прокси с поддержкой UDP/ICMP через мультиплексированные streams. Главное преимущество - не какая-то революционная архитектура, а то что протокол использует стандартные HTTP-методы (CONNECT), что делает трафик максимально похожим на обычное проксирование, а сам трафик идет через стримы.

Источник
 
Ничего не понятно, но очень интересно.
 
Я имел ввиду в чём конктретное отличие в шифровании , тунелировании, маскировки и буфера. Что трафик лишь может быть похожим на обычное проксирование но им не является.
Если нужно было оставить именно такой развернутый комментарий то впредь буду иметь ввиду.
А если я нарушил правила, то что же правила есть правила. Готов понести наказание по всей строгости. Но никаких иных целей я не преследовал.
 
Я пока посижу на WG в Казахстане за сто рублев
 
  • Теги
    ip tcp udp vpn
  • Назад
    Сверху Снизу