Нарушитель — цензор-провайдер: полная запись трафика, исходный код любого известного туннеля, пассивная классификация, репутационные списки. Ограничен не алгоритмами, а вычислительным ресурсом на магистрали. Механизмы ниже — из разведки и своего мониторинга из РФ; численные пороги — реконструкции источников, не наши измерения.
Соединение устанавливается, а затем замирает или сбрасывается по объёму, числу сессий и таймингам. Вложенный TLS-хендшейк детектируется по размерам и направлениям первых бёрстов; разрыв RTT транспорт/приложение паддингом не лечится.
3–12 параллельных TLS к одному IP или SNI за минуту дают заморозку 120 с; смена отпечатка под заморозкой — 600 с; повтор продлевает. Состояние по паре (IP назначения, отпечаток клиента). Клиент без мультиплекса попадает по построению.
Отпечаток клиента — ось классификации. Chrome/Safari/iOS на подозрительных префиксах под подозрением, Firefox/OkHttp проходят. Статический отпечаток любой библиотеки живёт месяцы и попадает в базу; ловится неточная копия браузера.
Весит больше формы протокола. Свежий IP живёт часы; один палящий сервис валит весь IP; несовпадение ASN сервера и владельца донора — пассивный признак. Форму протокола можно вылизать, репутацию адреса — нет.
Поток к адресам из подозрительных ASN замораживается после 16–20 КБ от сервера — TCP и QUIC одинаково. Диагностический признак: короткий ответ проходит, длинный обрывается на пороге.
Обращение к маркерному SNI или известному IP переводит абонента в бан к целому ASN на 5–15 мин. Выходной IP светится через российские приложения: двойные запросы к .ru и .com, RTT против геолокации.
Штатный режим в 64–77 регионах по расписанию. L3 CIDR не пробивается подменой SNI; живёт только TCP 80/443 к белым IP, UDP мёртв; релей в белом облаке закрыт административно с 24.01.2026. Фильтр L7 по SNI поверх L3.
Организатор распространения информации по 374-ФЗ хранит содержимое и ведёт ОТЛОЖЕННЫЙ выборочный офлайн-анализ медиапотоков — вне бюджета реального времени. Российский ОРИ по закону имеет доступ к расшифрованному WebRTC.
Алгоритмически цензор уже мог бы блокировать весь известный туннельный трафик поведенческим анализом и активным зондированием. Но на магистралях и у провайдеров идут терабиты в секунду, объём непрерывно растёт, и каждая новая проверка стоит вычислителя, памяти и риска сломать чужой законный трафик. Планка ставится не на неотличимость, а на стоимость фильтрации.
Клиент — статически слинкованное ядро на Rust; нода — отдельный бинарь, шарящий с клиентом крейты протокола и крипто. Управление ядром снаружи — только C-FFI, без слушающего сокета: не плодить сеть на устройстве и не давать палящий признак. Маршрутизатор потоков и детектор режима живут в ядре, не в клиентской обвязке.
pandora-crypto — обёртки RustCrypto/dalek. pandora-router — классификатор потоков + детектор режима. Формат профиля — спека-документ.
pandora-proto — внутренний протокол туннеля. pandora-tls — свой TLS-стек. pandora-profile — парсинг и подпись профиля.
pandora-transport — trait + T1..T5. pandora-media — WebRTC-фронт (T4). pandora-tmgr — менеджер и лимитер.
pandora-core — клиент, входы, C-FFI. pandora-node — серверный бинарь. pandora-cli — тестовый клиент и стенд.
Единый trait транспорта (наш аналог связки Dialer + Connector, терминология своя) плюс реестр модулей. Транспорт поднимает несущий канал — легитимную с виду сессию — и отдаёт протоколу дуплексный поток байт с контрактом: первый бёрст неотличим от начала настоящей сессии несущего. Форма — за транспортом, содержимое — за протоколом.
HTTP/2-подобный фрейминг с мультиплексом потоков поверх своего TLS к настоящему сайту за nginx на ноде. Неотличим от массового HTTPS/443, который доминирует по объёму (~84% трафика). Первый транспорт первого прохода, несёт основной объём.
Мимикрия под RTP и SIP на абонентском тракте — несущие реально ходят на last mile, отсечение дорого цензору по сопутствующему ущербу. Управляющий или деградированный объём, не основной.
UDP под конкретный разрешённый протокол. Годность зависит от эмпирики по операторам и радиодоступу: UDP на мобильных гасят по непохожести, QUIC цензурится по SNI. Включается там, где UDP проходит.
Узкий канал через белые резолверы — резерв под whitelist и шатдаун, заведомо низкая ёмкость. Последняя надежда для управления и обновления профиля, когда живёт лишь DNS к белым IP.
Полностью собственный стек TLS — свой парсер и сериализатор записей и сообщений рукопожатия, НЕ поверх rustls. Мотив: цензор блокирует не отпечаток Chrome, а его неточную копию от существующих инструментов; выживает только точная копия. Надстройка над готовой библиотекой позволяет влиять на ClientHello, но не на всё поведение — повторные соединения, серверную сторону, тайминги и размеры записей. Нам нужно целиком.
Сериализованные байты сверяются с эталонным браузером байт-в-байт, а не на глаз. Тестовые векторы — часть приёмки стека.
application_settings на повторных соединениях реальный Chrome ведёт иначе, чем имитации. Именно здесь имитацию и ловят.
X25519MLKEM768 в key_share — пост-квантовый гибрид, как у современного Chrome. Его отсутствие выдаёт устаревшую копию.
Корректные значения и размещение GREASE как у эталонного браузера, плюс расширение trust_anchors.
Post-handshake NST на серверной стороне и правдоподобное поведение возобновления сессии — не только первый хендшейк.
Поведение возобновления — часть отпечатка: реальный клиент отличается от имитаций именно на втором соединении.
Сквозной шифрованный канал клиент–нода, замешанный в первые кадры несущего транспорта. Второго рукопожатия нет: вложенный TLS-хендшейк детектируется по размерам и направлениям первых бёрстов. Несущий TLS считаем скомпрометированным — конфиденциальность и аутентификация лежат на этом слое, а не на несущем.
Нода имеет статический X25519-ключ из профиля; клиент знает его заранее и в первом сообщении доказывает владение своим статическим ключом. Незнакомцу нода отвечает как настоящий сайт несущего (anti-probing). 0-RTT сознательно отвергнут — риск повтора.
Первое сообщение клиента распылено по первым кадрам несущего: аутентификатор и эфемерный ключ по полям, не отдельным бёрстом. Размеры и направления повторяют начало легитимной сессии несущего (для T1 — вид начала H2).
ChaCha20-Poly1305, счётчиковый nonce на направление (не случайный — не повторяется по построению), скользящее окно антиреплея. Ключи направлений выведены HKDF-SHA256 из общего секрета.
Один туннель несёт N логических потоков (веб-соединения, DNS, медиа). Кадр = {поток, тип, длина, полезное}. Мультиплекс в 1–2 несущих соединения под общим лимитером — мало рукопожатий, профиль браузера.
В начале потока заявляется его профиль (5-tuple, тип, для медиа — параметры RTP/кодека); дальше идёт только изменяющаяся часть, статические заголовки сняты и восстанавливаются из состояния сессии. Дельта-кодирование по образцу ROHC и HPACK. На голосе заголовки до RTP бывают до 50% пакета — отсюда экономия.
Ре-кей по времени (час) и объёму (гигабайт) без разрыва потоков: новая эпоха подключей от того же секрета, старый ключ гасится после подтверждения. Отзыв клиента — снятие его статического ключа из реестра ноды, без ротации у всех.
Детектор режима — сам клиент: при белых списках до панели не достучаться. Он распознаёт blacklist / whitelist / шатдаун по пассивным и лёгким активным признакам (падение всего, кроме белых IP; гашение внешнего DNS и QUIC) и переключает набор доступных выходов и фронт, не роняя живые потоки без нужды.
Обычное состояние сети. Основной объём идёт транспортами основного объёма (T1 и т.д.); давление на цензора — ассортиментом непохожих обличий. Раздувание проверок толкает его в whitelist, дорогой для государства.
В 64–77 регионах по расписанию. Фронт — медиа-паразит внутри разрешённых сервисов; несёт не только сигналинг, но и ДЕГРАДИРОВАННЫЙ объём (узкий канал, просевшее качество). UI показывает уведомление о белых списках. Временное окно.
Спина проекта собирается последовательно, всё остальное вешается на неё параллельно. Порядок первого кода — протокол первым; ядро на Linux с интерфейсом на одну-две кнопки, обёртки-клиенты под платформы вторым этапом.
Параллельно и независимо: crypto, router, tls, profile и формат профиля. Свой TLS — самый крупный, ему больше времени. Критический путь стартует с crypto -> proto.
После crypto и proto: transport — T1 первым, он несёт объём; затем T2/T3/T5. media (T4) параллельно, после trait транспорта. Разные несущие — разные подзадачи, параллелятся между собой.
tmgr: динамическая схема транспортов, охранник соединений (лимитер под гранулярность цензора), карантин с экспоненциальной паузой, переключение фронтов по режиму сети.
На готовых крейтах параллельно: core (входы, конвейер, C-FFI), node (серверный бинарь, anti-probing), cli (стенд). Критический путь: crypto -> proto -> transport -> tmgr -> core.
Это техническое описание, не финальная спецификация: каждая капсула — черновик, в ней помечены открытые развилки [ОТКРЫТО] (серверная сторона несущего, модель соединений, шифрование профиля, порядок ввода несущих). Мы делимся устройством заранее, чтобы услышать коллег по отрасли: где мы недооцениваем противника, что упускаем, что сделали бы иначе. Замечания и разговор ценнее согласия.
Документ — черновик с открытыми развилками, и мы правда ждём критики: где недооценили противника, что упускаем, что сделали бы иначе. Замечания, вопросы и возражения присылайте на почту проекта — отвечаем каждому.