- PVSM.RU - https://www.pvsm.ru -
Привет! На днях AdGuard выложил в открытый доступ свой VPN-протокол, который назвал TrustTunnel. В статье разберемся, чем он отличается от того же VLESS и как устроен на самом деле.

AdGuard в своем анонсе заявляют, что любой VPN-протокол - это компромисс. Он либо быстрый, но легко детектится (WireGuard, OpenVPN, etc.), либо маскируется под обычный трафик, но тормозит.
Главная проблема тормозов в классическом подходе «устойчивых» протоколов - они обертывают VPN-данные в TCP-соединение и мимикрируют под HTTPS. Выглядит это в итоге как обычный веб-трафик, но TCP добавляет проблем со своим обязательным подтверждением доставки пакетов. При таком подходе, при потере одного пакета встаёт вся очередь пакетов, что приводит к классическому head-of-line blocking, жутко замедляя соединение.
Оповещаем о действиях РКН и новых блокировках в нашем телеграм [1]
VLESS (V2Ray/Xray) - популярный выбор для обхода блокировок. Протокол лёгкий, имеет минимумом фич, которые бы его замедляли и умеет маскироваться под HTTPS через TLS.
Но есть у него и нюанс - VLESS работает поверх TCP. Конечно можно использовать WebSocket, gRPC или QUIC как транспорт, но всё же для упрощения возьмем базовую схему - это TCP-обёртка со всеми вытекающими.
Плюс VLESS сам по себе не шифрует, а полагается на внешний TLS. Это гибко, но добавляет слой абстракции, а пользователи не всегда заморачиваются с этим.
На официальном сайте компании написано:
"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 [2]:
Для 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ы.
В спецификации [3] протокола нет собственного механизма буферизации. 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 [4] описаны параметры, влияющие на агрегацию:
|
Параметр |
Значение по умолчанию |
Описание |
|---|---|---|
|
|
16384 байт |
Максимальный размер HTTP/2 фрейма |
|
|
1350 байт |
Размер UDP-датаграммы для QUIC |
|
|
1350 байт |
Размер исходящих UDP-пакетов |
|
|
65536 байт |
Таблица сжатия HPACK |
|
|
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. По сути, всю софтварную задержку этим убрали:
Нет блокирующего потока, который «сидит и ждёт» N пакетов
Все данные сразу копируются в буфер библиотеки h2/quinn
Сама библиотека решает, когда делать flush и отправлять данные в фрейме
При медленной же сети TCP-буфер заполняется, а пакеты накапливаются в RAM. Когда сеть освобождается, TrustTunnel может отправить сразу серию фреймов
В конфиге max_frame_size (что очевидно из названия, такто!) задаёт верхний предел одного фрейма данных, а не фиксированный размер батча.
Просуммируем весь кайф протокола, который уменьшает его задержку еще раз:
Мультиплексирует много TCP-соединений в одну TLS-сессию. Не надо делать отдельный TLS handshake на каждое соединение.
Поддержка QUIC (HTTP/3) при использовании QUIC получаем отсутствие head-of-line blocking. Потеря пакета в одном stream не блокирует другие.
То, за что изначально боролась компания - энергоэффективность на мобильных устройствах - агрегация в HTTP стримы позволяет LTE-модему передавать данные одним разом и быстрее уйти в режим пониженного энергопотребления, вместо того чтобы посылать по одному пакету и не давать продыху.
И при всем этом он идеально маскируется под HTTPS: ведь буквально весь трафик выглядит как обычные CONNECT-запросы. DPI видит стандартный HTTP/2 over TLS.
И всё это теперь открыто под лицензией Apache 2.0 - можно форкать и использовать. Красота.
|
|
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), что делает трафик максимально похожим на обычное проксирование, а сам трафик идет через стримы.
Полезные ссылки: Спецификация протокола [3], Конфигурация [5], TrustTunnel на GitHub [6], Сайт проекта [7], Обсуждение на HN [8]
Оповещаем о действиях РКН и новых блокировках в нашем телеграм [1]
Автор: Network_know
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ip/442910
Ссылки в тексте:
[1] Оповещаем о действиях РКН и новых блокировках в нашем телеграм: https://t.me/femidasearch
[2] PROTOCOL.md: http://PROTOCOL.md
[3] спецификации: https://github.com/TrustTunnel/TrustTunnel/blob/master/PROTOCOL.md
[4] CONFIGURATION.md: http://CONFIGURATION.md
[5] Конфигурация: https://github.com/TrustTunnel/TrustTunnel/blob/master/CONFIGURATION.md
[6] TrustTunnel на GitHub: https://github.com/TrustTunnel/TrustTunnel
[7] Сайт проекта: https://trusttunnel.org/
[8] Обсуждение на HN: https://news.ycombinator.com/item?id=46708601
[9] Источник: https://habr.com/ru/companies/femida_search/articles/988466/?utm_source=habrahabr&utm_medium=rss&utm_campaign=988466
Нажмите здесь для печати.