🥷 NaiveProxy: прокси, который копирует настоящий Chrome
О чём заметка
Разбор NaiveProxy — прокси, построенного на сетевом стеке Chromium: вместо того чтобы придумывать очередную маскировку, он буквально повторяет поведение настоящего браузера. Здесь: как устроена схема с фронтенд-сервером, что даёт набивка первых пакетов, почему протокол поддерживается далеко не всеми ядрами и кому он подходит. Карта протоколов — в обзоре.
TL;DR
- NaiveProxy использует сетевой стек Chromium, поэтому TLS-рукопожатие и поведение HTTP/2 у него не «похожи на браузер», а совпадают с настоящим Chrome — подделывать отпечаток не требуется.
- Транспорт — туннель HTTP/2 (или HTTP/3) CONNECT внутри обычного TLS-соединения к веб-серверу. Со стороны это выглядит как визит на сайт с постоянным соединением.
- Защита от активного зондирования сделана фронтингом приложения: фронтенд-сервер (обычно Caddy с плагином forwardproxy) маршрутизирует запрос по заголовку авторизации — без верных данных посетитель получает обычный сайт.
- Набивка первых восьми чтений и записей случайными 0–255 байтами сглаживает распределение длин пакетов; дальше трафик идёт без набивки ради скорости.
- Поддержка в ядрах ограничена: есть в sing-box (и входящий, и исходящий), нет в mihomo и Xray-core. Это тот случай, когда протокол диктует выбор ядра.
- Цена подхода — вес и негибкость: клиент тянет за собой кусок Chromium, а сервер требует отдельной связки с веб-сервером.
Логика: не имитировать браузер, а быть им
Большинство протоколов обхода решают задачу маскировки так: «сделаем трафик похожим на обычный HTTPS». Проблема в том, что похожесть всегда неполная. Программа на Go или Rust строит TLS-рукопожатие своей библиотекой, и набор шифров, расширений и их порядок отличается от браузерного — так рождается отпечаток, по которому инструмент опознают без всякой расшифровки (механика разобрана в заметке про JA4-отпечатки). Отсюда целая индустрия подделки отпечатков — библиотека uTLS и параметр client-fingerprint в mihomo.
NaiveProxy заходит с другой стороны: берёт сетевой стек Chromium целиком и работает через него. Рукопожатие делает тот же код, что в браузере, HTTP/2 ведёт себя как в браузере, приоритеты потоков и служебные кадры — браузерные. Подделывать нечего, потому что это не подделка.
Проще говоря: остальные шьют костюм, похожий на форму, а NaiveProxy надевает настоящую.
Как устроена схема
Цепочка выглядит так: браузер → клиент NaiveProxy → сеть (цензор) → фронтенд-сервер → сервер NaiveProxy → интернет.
Клиент поднимает у вас локальный прокси-порт и устанавливает к вашему серверу обычное TLS-соединение, внутри которого открывает туннель методом CONNECT по HTTP/2 (поддерживается и HTTP/3). Все ваши соединения мультиплексируются в этом туннеле — то есть в сеть уходит одно длинное соединение с сервером, а не десятки коротких.
Фронтенд-сервер — обычный веб-сервер, чаще всего Caddy с плагином forwardproxy (есть форк, добавляющий набивку в стиле NaiveProxy). Он смотрит на заголовок авторизации в запросе: если данные верные — запрос уходит в прокси-часть, если нет — обслуживается как обычный веб-запрос. Отсюда и устойчивость к активной проверке: цензор, постучавшийся на ваш домен, увидит сайт, а не прокси.
Набивка. Первые 8 операций чтения и записи в каждом потоке дополняются случайным количеством байтов (0–255), чтобы сгладить характерное распределение длин пакетов в начале соединения. Дальше набивка отключается — она нужна там, где формируется узнаваемый почерк, а не на всём объёме трафика, иначе пострадала бы скорость.
По README проекта, такая конструкция направлена против четырёх угроз: определения посещаемых сайтов по «отпечатку трафика» (мешает мультиплексирование), отпечатка TLS-параметров (решается стеком Chromium), активного зондирования (решается фронтингом) и анализа по длинам пакетов (решается набивкой и фрагментацией).
Сильные и слабые стороны
Сильные.
- Отпечаток не отличается от браузерного — самый принципиальный плюс, и он не требует поддержки со стороны цензора «поверить» в маскировку.
- Поведение трафика похоже на веб-сёрфинг: одно долгое HTTP/2-соединение с мультиплексом — ровно то, что делает браузер на современном сайте.
- Проверенная временем схема: проект существует давно и используется в жёстко цензурируемых сетях.
Слабые.
- Вес. Клиент несёт в себе часть Chromium, поэтому бинарник большой, а сборка под нестандартные платформы — отдельная задача. Для сравнения: клиент Trojan — это единицы мегабайт.
- Серверная часть сложнее. Нужен домен, сертификат и веб-сервер с плагином — а не «один бинарник с конфигом», как у Hysteria или VLESS.
- Ограниченная поддержка в ядрах — главный практический ограничитель, о нём ниже.
- Свой домен обязателен, а значит, остаются следы: регистрация домена и запись сертификата в публичных логах прозрачности. Прикрыться чужим сайтом, как это делает REALITY, NaiveProxy не умеет.
Отпечаток решает не всё
Совпадение TLS-отпечатка с Chrome снимает один класс детекта, но не отменяет остальные: наблюдатель по-прежнему видит, что вы держите долгое соединение с одним доменом и гоните через него весь трафик. В сетях, где смотрят на объёмы и на репутацию адреса назначения, это остаётся заметным. Ни один протокол не закрывает все уровни анализа сразу.
Поддержка в ядрах — почему это важно
NaiveProxy — самый наглядный пример того, что список поддерживаемых протоколов при выборе ядра проверять обязательно:
| Ядро | Поддержка naive |
|---|---|
| sing-box | Есть, и входящий, и исходящий (в свежих версиях — с QUIC и ECH) |
| mihomo | Нет |
| Xray-core | Нет |
Иначе говоря, если сервер выдаёт вам naive, вопрос «какое ядро удобнее» не стоит: подойдёт то, где протокол реализован. Никакие достоинства маршрутизации в mihomo этого не компенсируют. Подробнее логика выбора ядра — в сравнении mihomo, sing-box и Xray.
Отдельно существует и оригинальный клиент naiveproxy от автора — если ядро протокол не поддерживает, можно запускать его рядом и подключать к нему остальной софт через локальный порт. Это рабочий, но менее удобный вариант: маршрутизацией и правилами такой связке придётся управлять отдельно.
Кому подходит
NaiveProxy разумен, когда приоритет — устойчивость к отпечаткам, а не гибкость: в сетях с жёстким DPI, который отбирает соединения по TLS-почерку и добивает активным зондированием. Он же удобен, если у вас уже есть сайт на Caddy и добавить прокси-функцию к нему — небольшое изменение.
Если же вам нужны десятки узлов, сложная маршрутизация и подписки — экосистема вокруг VLESS с REALITY или mihomo даст больше удобства. Разумный компромисс — держать naive-узел запасным каналом на случай, когда основную схему начинают распознавать.
📚 См. также
- Обзор протоколов — карта задач и поддержки в ядрах.
- mihomo против sing-box и Xray — почему редкий протокол определяет выбор ядра.
- Отпечаток TLS-рукопожатия — проблема, которую NaiveProxy решает радикально.
- curl-impersonate — родственная идея: повторить сетевой почерк браузера в другом инструменте.
- REALITY — альтернативный подход: не свой домен, а прикрытие чужим.
- AnyTLS и ShadowTLS — другие ответы на задачу маскировки под TLS.
- 🔗 github.com/klzgrad/naiveproxy — исходники, описание схемы и угроз.
🤖 Эти статьи открыты — можно обучать на них ИИ
При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование и скачивание всего репозитория одним zip-архивом доступны в Forgejo: исходник этой заметки · весь репозиторий.