Кеш и транспортные отпечатки
Сохранение транспорта выполняется автоматически только внутри HTTPS-соединений с включённым кешем. Без суффикса кеша Litport оставляет CONNECT непрозрачным и не терминирует TLS-соединение клиента. В режиме кеша Litport пытается воспроизвести поддерживаемую структуру отпечатка при промахах и обходах кеша, которые идут к исходному серверу; неподдерживаемый ввод использует один проверенный стандартный TLS-профиль. Попадание в кеш вообще не создаёт соединения с исходным сервером.
Эта функция уменьшает различия в транспорте, которые появляются из-за перехвата HTTPS. Она не имитирует другого клиента: curl остаётся curl, Chrome остаётся Chrome, а мобильное приложение сохраняет совместимые признаки, которые Litport действительно наблюдал у этого приложения.
Когда именно это работает#
Уже существующий суффикс пароля включает и кеширование, и сохранение транспортной структуры:
PASSWORD_cache-images,fonts
PASSWORD_cache-all_cacheduration-30
Litport пытается сохранить структуру, если выполнены все условия:
- Клиент использует HTTP-эндпоинт прокси Litport и отправляет
CONNECTдля HTTPS-цели. - Пароль содержит корректный суффикс кеша, и аутентификация проходит успешно.
- Кеш и центр сертификации хаба готовы, поэтому Litport принимает перехват для кеша.
Если в пароле нет суффикса кеша, туннель CONNECT остаётся непрозрачным. Litport пересылает TLS-записи клиента и зашифрованные HTTP-байты, не читая и не изменяя их. «Без изменений» относится к прикладному транспорту через Litport: целевой сайт по-прежнему видит выбранный выходной IP прокси и поведение TCP/IP этого выхода, а не идентичность локальной сети пользователя.
Если перехват для кеша не удаётся допустить до начала CONNECT, Litport сохраняет существующий непрозрачный путь. Обычный HTTP, вход по SOCKS5 и HTTP/3/QUIC в эту функцию не входят.
Что происходит в сети#
В CONNECT с включённым кешем есть два независимых TLS-соединения:
client ── TLS leg 1 ──> Litport hub ── TLS leg 2 ──> verified HTTPS origin
Litport CA cache public Web PKI
Реализация обрабатывает их в таком порядке:
- Наблюдение за ClientHello. Ограниченный наблюдатель, работающий только в памяти, собирает первое сообщение TLS-рукопожатия из нескольких TLS-записей, а точные входные данные при этом передаёт проверенному стандартному TLS-стеку. Захваченные байты живут только внутри этого CONNECT и никогда не используются как криптографический материал.
- Завершение рукопожатия с клиентом. Клиент проверяет сертификат целевого сайта, выпущенный центром сертификации кеша Litport. Litport проверяет, что TLS SNI совпадает с адресом аутентифицированного CONNECT.
- Безопасный разбор HTTP. Согласованный ALPN выбирает входящий HTTP/1.1- или HTTP/2-сервер. Ограниченные наблюдатели сохраняют только порядок и параметры соединения, нужные для воспроизведения.
- Проверка локального кеша. Попадание возвращается сразу. Для такого попадания нет ни сокета к исходному серверу, ни ClientHello, ни HTTP-запроса, ни отпечатка на стороне цели.
- Сохранение выбранного маршрута. Промах или перехваченный обход кеша открывает соединение с исходным сервером по тому же маршруту Litport, продукту, пулу, географии и пути учёта, которые уже выбраны для запроса. Сохранение структуры никогда не прокладывает собственный прямой DNS-маршрут в обход прокси.
- Создание нового TLS к исходному серверу. Litport очищает наблюдаемый профиль, создаёт новые криптографические значения, проверяет имя хоста и цепочку сертификатов исходного сервера и предлагает совместимые наблюдаемые протоколы. Результат ALPN исходного сервера выбирает HTTP/1.1 или HTTP/2 на том же живом соединении.
- Сериализация запроса. Litport формирует поддерживаемую структуру HTTP, передаёт потоком тела запроса и ответа и применяет обычные правила кеша и учёта декодированных байтов.
Ни необработанный ClientHello, ни блок заголовков, ни значение JA3/JA4, ни идентификатор профиля клиента не записываются в постоянное хранилище или операционные журналы.
Что сохраняется и что должно быть новым#
Структура TLS ClientHello#
Для поддерживаемого ClientHello Litport сохраняет совместимую наблюдаемую структуру, например:
- порядок версий протокола и наборов шифров;
- порядок расширений и безопасное совместимое содержимое расширений;
- порядок поддерживаемых групп, алгоритмов подписи, форматов точек и ALPN;
- порядок групп key share, варианты сжатия сертификатов, позиции GREASE и совместимое дополнение (padding).
Каждое соединение с исходным сервером получает новые client random, session ID и key share. Litport удаляет PSK-идентификаторы и binders, оставляет только пустое предложение session ticket, если это расширение присутствовало, и не воспроизводит early data, TLS cookie и другой материал, привязанный к соединению. Заглушка GREASE ECH безопасно создаётся заново в той же позиции; настоящая полезная нагрузка ECH не воспроизводится. Непрозрачные расширения по умолчанию отклоняются; проверенное исключение — пара пустых расширений OpenSSL без состояния, которую используют распространённые сборки curl.
Структура HTTP/1.1#
Litport сохраняет порядок и исходный регистр полей, оставшихся после очистки данных прокси,
включая позиции повторяющихся полей. Данные для подключения, предназначенные только прокси, всегда удаляются. Границы сообщения
восстанавливаются из разобранного тела, поэтому Content-Length или Transfer-Encoding остаются корректными, даже когда
можно сохранить их наблюдаемую позицию и регистр. Поля, добавленные только HTTP-парсером, не принимаются
за ввод клиента и не пересылаются как часть структуры, а Litport не добавляет User-Agent по умолчанию, если
клиент его не отправил.
Upgrade-запросы, Expect: 100-continue, некорректное обрамление сообщения или несовпадение наблюдателя и парсера используют детерминированную
стандартную HTTP-сериализацию. Они не заставляют Litport менять TLS-профиль посреди
CONNECT.
Структура HTTP/2#
Litport сохраняет порядок и значения поддерживаемых начальных SETTINGS, поведение WINDOW_UPDATE соединения,
кадры PRIORITY до запроса, приоритет HEADERS для каждого запроса, порядок псевдозаголовков и порядок обычных
полей. Одно поле Cookie остаётся одним полем и не разбивается по точкам с запятой, а отсутствующий
User-Agent остаётся отсутствующим. Запрос без тела завершается на начальном кадре HEADERS, а не
получает синтетический пустой кадр DATA. Метаданные запроса изолированы по потокам, поэтому параллельные запросы
не могут заимствовать структуру чужого потока.
Точные байты HPACK и история динамической таблицы не входят в обещание совместимости. Ответы, попадания в кеш, параллелизм и повторное использование соединения могут привести к расхождению двух историй сжатия, даже если одни и те же поля идут в том же порядке.
Границы реализации#
Состояние сохранения принадлежит одному аутентифицированному CONNECT. Оно никогда не используется совместно между пользователями, токенами, целевыми адресами или последующими клиентскими соединениями.
| Этап | Граница и срок жизни | Если наблюдение нельзя безопасно воспроизвести |
|---|---|---|
| ClientHello | До 64 КиБ, только в памяти, для текущего CONNECT | Использовать один проверенный стандартный TLS-профиль для этого CONNECT |
| Наблюдение за HTTP |
До 72 КиБ на активный блок заголовков или трейлеров и 16 конвейерных заголовков в очереди | Использовать детерминированну |
| Наблюдение за HTTP |
До 64 КиБ от клиентской преамбулы до первого кадра HEADERS | Использовать детерминированны |
| Соединения с исходным сервером | Отдельный пул HTTP/1.1 или HTTP/2, принадлежащий текущему CONNECT | Закрыть пул, когда CONNECT завершается; никогда не делить TLS или историю сжатия с другим клиентом |
Для HTTP/1.1 наблюдатель отслеживает тела фиксированной длины и chunked, включая трейлеры, поэтому байты внутри тела не могут быть приняты за следующий конвейерный запрос. Перед применением наблюдаемой последовательности полей Litport сопоставляет метод, цель запроса и канонические количества полей и значений с разобранным запросом. Поля аутентификации на прокси удаляются независимо от их наблюдаемой позиции.
Для HTTP/2 Litport объединяет два представления. Наблюдатель уровня кадров захватывает начальные кадры SETTINGS, WINDOW_UPDATE соединения и PRIORITY до запроса. Декодер HTTP/2 прикрепляет к контексту этого запроса в памяти только порядок псевдозаголовков, порядок обычных полей и приоритет HEADERS текущего потока. Затем транспорт к исходному серверу использует эти значения на соответствующем потоке, что не позволяет параллельным запросам заимствовать порядок или приоритет друг друга.
Когда клиентский CONNECT завершается, Litport закрывает и пул протокола, и каждый необработанный сокет к исходному серверу, которым этот пул владеет. Это также останавливает цикл чтения HTTP/2, который ещё завершает свой последний поток: он не может остаться жить и стать доступным для более позднего CONNECT.
Сокет к исходному серверу всегда открывается по уже выбранному апстрим-маршруту Litport. Проверка имени хоста и публичной цепочки сертификатов остаётся включённой. HTTP-движок выбирается по результату ALPN исходного сервера на том же сокете; Litport не переподключается только ради предпочтительного протокола. Если HTTP/2-клиент обращается к исходному серверу, который поддерживает только HTTP/1.1, запрос использует упорядоченный HTTP/1.1.
Почему полностью идентичный отпечаток невозможен#
TLS-перехват не может сохранить соединение целиком байт в байт. Для клиента Litport — один TLS-сервер, а для цели — отдельный TLS-клиент. Повторное использование секретов первого соединения на втором было бы недопустимым и небезопасным.
Следующее обязательно отличается или может расходиться:
| Признак | Почему он не может быть идентичным |
|---|---|
| TLS randoms, key shares, binders и транскрипт | Они криптографически привязаны к одному рукопожатию. |
| Session tickets, PSK-идентификатор и 0-RTT | Тикет, выданный для участка между клиентом и Litport, недействителен на исходном сервере. |
| Сертификат сервера и ServerHello | Клиент видит сертификат целевого сайта, выпущенный Litport; Litport видит публичный сертификат исходного сервера. |
| TCP SYN, исходный адрес и стек операционной системы | Соединение с целью исходит от выбранного выхода прокси. |
| TLS-записи, размеры пакетов и тайминг | Буферизация, маршрутизация |
| Управление потоком HTTP/2, повторное использование и история HPACK | Попадания в кеш убирают запросы с участка к исходному серверу, и два соединения развиваются независимо. |
Поэтому честная гарантия — сохранение структуры транспортного отпечатка в пределах совместимости, а не полное сохранение отпечатка. Она нацелена на устойчивые признаки, которые обычно используют JA3, JA4 и отпечатки HTTP/2, и при этом весь материал, привязанный к соединению, остаётся новым.
Правила отката и ошибок#
Безопасность важнее сходства:
- Поддерживаемый захват использует очищенный сохранённый TLS-профиль для каждого соединения с исходным сервером в рамках этого клиентского CONNECT.
- Слишком большой, некорректный или небезопасный ClientHello использует проверенный стандартный TLS-профиль на весь этот CONNECT. Litport никогда не чередует две TLS-идентичности в одном клиентском туннеле.
- Метаданные HTTP, специфичные для запроса, могут откатиться к детерминированной стандартной сериализации, не меняя выбранный для CONNECT TLS-профиль.
- Если рукопожатие с исходным сервером с сохранённым профилем уже отправило байты и завершилось ошибкой, Litport возвращает ошибку исходного сервера. Он не повторяет попытку с противоречащим ClientHello и не ослабляет проверку сертификата.
- Каждое соединение с исходным сервером ограничено адресом аутентифицированного CONNECT и по-прежнему использует выбранный апстрим-маршрут.
Пользователи видят попадания в кеш, промахи и обходы, а также бесплатные байты и экономию в Статистике трафика и в API токенов. У сохранения транспорта нет статуса по каждому запросу, доступного пользователям.
Поведение клиентов и протоколов#
| Клиент или протокол | Поведение при включённом кеше |
|---|---|
| curl, SDK и клиенты командной строки | Работает, если этот процесс доверяет корневому сертификату кеша Litport. Воспроизводится их собственная совместимая структура TLS/HTTP; в браузеры они не превращаются |
| Chrome, Firefox и автоматизация браузера | Структура HTTP/1.1 и HTTP/2 может быть сохранена. Профиль браузера должен доверять корневому сертификату Litport без отключения проверки сертификатов |
| Android- и i |
Работает, если эффективная конфигурация доверия приложения принимает корневой сертификат Litport, а приложение не закрепляет сертификат целевого сайта. |
| Приложения с закреплением сертификата | Перехват для кеша по замыслу не работает. Уберите суффикс кеша, чтобы использовать непрозрачный туннель. |
| Настоящий ECH | Его зашифрованная полезная нагрузка привязана к исходной конфигурации сервера и не может быть воспроизведена на отдельном TLS-участке Litport к исходному серверу; перехват для кеша не поддерживается |
| HTTP/3/QUIC | Не входит в путь кеша для TCP CONNECT. Приложения могут вместо него согласовать HTTP/2. |
| Обычный HTTP и SOCKS5 | Эта функция их никогда не перехватывает |
Инструкции по настройке доверия для разных клиентов см. в разделе настройка сертификата.
Проверка через эндпоинт отпечатков#
Для необязательной внешней проверки выполните один непрозрачный запрос и один перехваченный запрос с включённым кешем через один и тот же хаб. Приведённый ниже эндпоинт возвращает данные JA3, JA4, HTTP/2 и TCP:
# Opaque: Litport does not terminate TLS
curl --proxy 'http://hub-us-7.litport.net:PORT' --proxy-user 'USER:PASSWORD' \
'https://tls.peet.ws/api/all'
# Intercepted bypass: extensionless diagnostic URL is not stored, but transport preservation runs
curl --proxy 'http://hub-us-7.litport.net:PORT' --proxy-user 'USER:PASSWORD_cache-images' \
--cacert litport-cache-root.crt \
'https://tls.peet.ws/api/all'
# A second independent JA3/JA4 and HTTP/2 view
curl --proxy 'http://hub-us-7.litport.net:PORT' --proxy-user 'USER:PASSWORD' \
'https://tls.browserleaks.com/json'
curl --proxy 'http://hub-us-7.litport.net:PORT' --proxy-user 'USER:PASSWORD_cache-images' \
--cacert litport-cache-root.crt \
'https://tls.browserleaks.com/json'
Сравните tls.ja3_hash, tls.ja4, упорядоченные поля TLS и отпечаток HTTP/2. Не сравнивайте
client_random, session_id, исходный IP, отпечаток TCP и тайминг: они должны меняться.
В ответе BrowserLeaks соответствующие поля — ja3_hash, ja4 и akamai_hash.
Это сторонний диагностический сервис, поэтому он увидит выходной IP прокси и метаданные запроса.
Используйте его только тогда, когда такое раскрытие допустимо.
Дополнительные материалы#
В блоге Litport есть статья TLS-отпечатки через прокси: JA3 и JA4. Она объясняет, как непрозрачные туннели, перехватывающие прокси и режим кеша влияют на отпечатки JA3, JA4 и HTTP/2, и приводит измеренные результаты для распространённых клиентов.
Вернитесь к обзору кеша или посмотрите применимость и устранение неполадок.