🦎 ТСПУ режет TLS с адресов Google и считает TCP-окно: недоступные узлы googlevideo, wssize 1:1 и NextDNS (октябрь 2026)

О чём заметка

С 23 по 31 октября 2026 года участники темы обсуждения zapret2 на форуме ntc.party и разработчик zapret (ник bolvan) по кусочкам собирали картину нового поведения ТСПУ (Технические Средства Противодействия Угрозам, оборудование фильтрации Роскомнадзора у операторов). Часть зарубежных видеосерверов Google перестала открываться через Zapret 2, хотя через VPN работает. Оказалось, что фильтр запрещает любой TLS с отдельных адресов и узнаёт TLS по ответу сервера, причём читает этот ответ только в пределах TCP-окна, которое объявил клиент. Здесь разобрано, что именно нашли, как это устроено, почему помогает крошечное окно wssize 1:1 и чем за это приходится платить. Отдельным разделом идёт случай dns.nextdns.io, где тот же учёт окна ломает работу и Zapret, и самого фильтра.

Статус данных

Почти всё здесь — наблюдения пользователей форума и выводы разработчика zapret, сделанные из России на разных провайдерах. Роскомнадзор и операторы механизм не описывали, поэтому слова «фильтр делает X» означают «так ведёт себя трафик в проверках участников». Собственные замеры для заметки сделаны 31 октября 2026 года с зарубежного сервера: они проверяют устройство ответа сервера, адреса и владельцев сетей, но поведение ТСПУ оттуда не видно. Поведение фильтра различается по операторам и меняется со временем: то, что работало 24 октября, у части людей перестало работать 25-го.

TL;DR

  • С 24 октября 2026 года часть узлов *.googlevideo.com за рубежом (адреса Google 74.125.x.x, по подсчёту участников это Гамбург, Франкфурт, Варшава, Амстердам) не открывается через Zapret, но работает через VPN. Российские кэши Google внутри операторов при этом работают. Жалобы идут с разных провайдеров, включая Ростелеком.
  • Подмена имени в запросе не помогает: соединение с адресом 74.125.110.38 не проходит даже с именем example.com. Фильтр запрещает любой TLS с конкретных адресов.
  • Под фильтр попадают не подсети и не города, а отдельные группы серверов Google по 32 адреса. Их видно по обратной записи DNS: 74.125.110.38 — группа ham11s03 в Гамбурге, а «рабочий сосед» 74.125.110.70 из той же подсети — группа sof02s30 в Софии. В Варшаве и Франкфурте одни группы недоступны, а другие работают. В реестре Роскомнадзора ни одного из этих адресов нет, и по какому признаку выбраны группы, по открытым данным не видно.
  • TLS фильтр узнаёт по ответу сервера, а не по запросу клиента. Ответ он читает только в пределах окна приёма, объявленного клиентом. Если через wssize сжать окно до 2 байт, фильтр не видит даже начала записи TLS, и ответ проходит.
  • Цена такого приёма — скорость. Множитель окна фиксируется в начале соединения, поэтому после wssize 1:1 окно остаётся, например, в 64 раза меньше задуманного до конца соединения. При пинге 20 мс одно соединение получает около 1,6 Мбит/с, этого мало для видео в 720p.
  • Для googlevideo фильтр около 10 минут помнит, чем кончилось соединение с тем же портом и адресом, и не реагирует на RST. На bbc.com и meduza.io так не происходит: похоже, для Google сделано отдельное правило.
  • Начало ответа 16 03 03 — не ошибка и не добавка Google, а требование стандарта TLS для любого сервера. Одинаково у TLS 1.2 и TLS 1.3 оно намеренно: в 2017 году новый номер версии ломал около 6% соединений на старом сетевом оборудовании, и TLS 1.3 замаскировали под TLS 1.2. Этой неизменной подписью и пользуется фильтр, чтобы узнать TLS по трём байтам.
  • Учёт окна объясняет и случай dns.nextdns.io: сервер даёт клиенту окно в 1 448 байт, а приветствие TLS 1.3 с постквантовым ключом длиннее, поэтому Zapret 2 не собирает его целиком и не узнаёт имя. Выход — фильтровать такой сервер по адресу через ipset, а не по списку доменов.

Что происходит и что ломается

Короткий ответ: в конце октября 2026 года фильтр научился (или начал чаще применять) три вещи. Он запрещает любой TLS с отдельных групп серверов Google, не глядя на имя сайта. TLS он узнаёт не только по запросу клиента, но и по ответу сервера, а при TLS 1.2 может прочитать в ответе и само имя. И ответ сервера, и поддельные пакеты обхода он читает только в пределах TCP-окна. Всё, что сломалось за эту неделю, вытекает из этих трёх свойств. Недоступные узлы Google находили у абонентов Ростелекома в разных округах и у других провайдеров, обрыв QUIC — у МегаФона, память фильтра на 10 минут — у Ростелекома и екатеринбургской «Планеты». Поэтому участники считают это работой ТСПУ, а не отдельного провайдера; официально этого никто не подтверждал.

У зрителя и пользователя ломается вот что.

Что ломаетсяКак это выглядитПочемуЧто пока работает
Видео YouTube с зарубежных узлов Googleролик не стартует или идёт рывками, когда плеер выбрал узел 74.125.x.x из попавшей под фильтр группы серверов; в инструментах разработчика запросы videoplayback к одному узлу висятс адреса узла не пропускается никакой TLS, какое бы имя ни стояло в запросеролики с российского кэша Google; VPN; другие группы серверов Google, в том числе соседние блоки той же подсети, которые стоят в других городах
YouTube и другие сервисы на старых устройствахприложения на TLS 1.2 (системные программы Windows 10, старые телевизоры, приставки, телефоны) перестают открываться со стратегией, которая мелко режет приветствиефильтр проверяет имя в сертификате, который при TLS 1.2 идёт открытым текстомwssize, то есть медленное соединение
HTTP/3 к видеосерверамбраузер сначала пробует QUIC, ждёт тайм-аута и только потом переходит на TCPпо наблюдению на МегаФоне, UDP-пакеты к *.googlevideo.com на порт 443 обрываются на ТСПУсоединение по TCP, отключение QUIC в браузере
DNS поверх HTTPS у NextDNSdns.nextdns.io не отвечает, хотя похожая стратегия работает для других сайтовсервер даёт клиенту окно 1 448 байт; длинное приветствие TLS 1.3 и длинный поддельный пакет в него не влезаютотбор трафика по адресу вместо списка доменов, короткий поддельный пакет

У тех, кто обходит блокировки, ломается другое:

  • Приёмы, которые прячут имя сайта, бесполезны против фильтра по адресу. Нарезка приветствия, поддельные пакеты, перестановка сегментов скрывают SNI, а этому фильтру SNI не нужен: ему достаточно увидеть, что с запрещённого адреса пришёл TLS.
  • Blockcheck ничего не находит. На таких адресах перебор стратегий выдаёт пустой результат. По словам rkn-chan, blockcheck не смотрит, подтвердил ли сервер получение приветствия, поэтому не замечает, что приветствие уже прошло фильтр, а застревает ответ сервера.
  • Найденные стратегии живут сутки. Связка multisplit с wssize, работавшая у участника 24 октября, 25-го перестала помогать. Списки узлов, проверенные утром, вечером дают другой результат.
  • Единственный надёжный приём дорог. wssize 1:1 проходит фильтр, но режет скорость соединения в десятки раз до самого его конца, а включать его можно только по спискам адресов, которые приходится собирать вручную.
  • Длинные поддельные пакеты перестают работать там, где окно маленькое. Фильтр обрезает поддельное приветствие по окну и не может его разобрать, поэтому поддельное приветствие с постквантовым ключом не обманывает его на серверах вроде NextDNS.
  • Для Google фильтр помнит исход соединения около 10 минут. Удачное соединение с тем же портом проходит повторно и без обхода, а неудачное так же долго остаётся заблокированным. На других сайтах участники такого не нашли.

Ниже всё это разобрано по порядку: сначала хроника, затем устройство ответа сервера, список узлов, механизм с окном, цена wssize и случай NextDNS.

Хроника: от «капризов с TLS 1.2» до блокировки по адресу

Разговор начался не с googlevideo. 19 октября 2026 года в той же теме обсуждали, что видео YouTube у абонентов Ростелекома снова идёт ровно, после того как российский кэш Google снова стал работать. Кэш Google (GGC, Google Global Cache) — это сервер Google внутри сети оператора, который раздаёт популярные ролики без выхода за рубеж; как он устроен и как его опознать по имени узла, описано в отдельной заметке. Такие кэши в октябре 2026 года работали, и речь дальше пойдёт не о них, а о зарубежных узлах Google, куда плеер отправляет зрителя, когда своего кэша нет или он не подходит.

23 октября участник rkn-chan заметил новую особенность фильтра при TLS 1.2: если слишком мелко нарезать настоящее приветствие клиента функцией multisplit, фильтр как будто «сдаётся» на нём и начинает проверять ответ сервера. 24 октября посыпались сообщения о конкретных недоступных узлах googlevideo, 25-го люди начали проверять их списками, а 29-го rkn-chan и bolvan нашли механизм. 30–31 октября тот же механизм всплыл в совсем другом случае, с DNS-сервером NextDNS.

Как фильтр может прочитать ответ сервера

Защищённое соединение по HTTPS начинается с рукопожатия TLS (Transport Layer Security, протокол шифрования, на котором стоит HTTPS). Клиент первым отправляет приветствие, в котором открытым текстом называет имя сайта. Это приветствие называется ClientHello, а поле с именем — SNI (Server Name Indication). Обычно фильтр ТСПУ решает судьбу соединения именно по нему, и почти все стратегии Zapret нацелены на то, чтобы фильтр не смог это имя прочитать: режут приветствие на куски, подмешивают поддельные пакеты, переставляют сегменты.

Сервер отвечает своим приветствием (ServerHello), а следом присылает сертификат, который подтверждает, что это действительно он. Здесь две версии TLS расходятся. В TLS 1.2 сертификат идёт открытым текстом (RFC 5246), а в нём перечислены имена, для которых он выдан. В TLS 1.3 открытыми остаются только приветствия, а все сообщения после ServerHello шифруются, включая сертификат.

Для этой заметки ответ одного из узлов, 74.125.110.70 с именем rr1---sn-i5heen7s.googlevideo.com, записан 31 октября 2026 года в обеих версиях. В TLS 1.2 сервер прислал ServerHello на 63 байта и сертификат на 4 315 байт, в котором строка googlevideo.com встречается четыре раза. В TLS 1.3 после открытого ServerHello на 122 байта шла одна зашифрованная запись на 4 477 байт, и строки googlevideo.com в сырых байтах ответа не нашлось. Но оба ответа начинаются с одних и тех же байтов 16 03 03 00: это заголовок записи TLS, где 16 означает «рукопожатие», а 03 03 — номер версии, который TLS 1.3 ради совместимости пишет так же, как TLS 1.2.

Проще говоря: при TLS 1.2 сервер сам называет своё имя в ответе, и фильтр может проверить его там, если не смог прочитать запрос. При TLS 1.3 имени в ответе не видно, но то, что это TLS, видно по первым же байтам.

Байты 16 03 03 — не ошибка Google, а требование стандарта TLS

Эти байты не придумал ни Google, ни фильтр, и это не сбой на стороне Google: так начинается любая запись TLS у любого сервера, от Cloudflare до NextDNS. Записью называется порция данных, на которые TLS режет поток, и у каждой есть заголовок из пяти байтов (раздел 5.1 RFC 8446). Первый байт сообщает тип содержимого: 16 в шестнадцатеричной записи, то есть 22, означает сообщение рукопожатия, 14 (20) — служебную смену шифра, 17 (23) — уже зашифрованные данные, 15 (21) — предупреждение об ошибке. Следующие два байта — номер версии, последние два — длина записи. В ответе узла Google на TLS 1.3 заголовок 16 03 03 00 7a читается так: рукопожатие, версия 3.3, дальше 122 байта ServerHello. В TLS 1.2 он был 16 03 03 00 3f, то есть 63 байта.

Странный номер версии тянется из истории. Протокол TLS вырос из SSL 3.0 и сохранил его нумерацию: SSL 3.0 записывается как 03 00, TLS 1.0 как 03 01, TLS 1.1 как 03 02, TLS 1.2 как 03 03. Логично было бы, чтобы TLS 1.3 писал 03 04, и в черновиках стандарта так и было. Но в феврале 2017 года, когда Chrome и Firefox начали включать TLS 1.3 части пользователей, оказалось, что многие сетевые устройства посередине пути (корпоративные прокси, фильтры, системы проверки трафика) рвут соединения с незнакомым номером. По данным Cloudflare, в пробе Chrome на серверах Gmail успешно завершались 98,3% соединений по TLS 1.2 и только 92,3% по TLS 1.3. Около 6% соединений по новой версии ломались сверх обычного, хотя ни сервер, ни клиент ошибок не делали.

Поэтому TLS 1.3 замаскировали под TLS 1.2. В заголовке записи и в основном поле версии стандарт требует писать 03 03, а настоящая версия передаётся в расширении supported_versions, которое старые устройства просто пропускают. Тот же стандарт описывает и режим совместимости с такими устройствами (приложение D.4 RFC 8446): клиент присылает идентификатор сессии, как при возобновлении старого соединения, а стороны вставляют пустое сообщение смены шифра, хотя TLS 1.3 оно не нужно. Его видно и в замере ответа Google: сразу после ServerHello идёт запись 14 03 03 00 01 01, один байт смены шифра.

Сами байты Google не добавлял, а его серверы пишут ровно то, что велит стандарт. Роль Google в этой истории другая. Проба на Gmail, которая показала поломки, была его, а среди тех, кто сканировал интернет в поисках сломанных серверов, Cloudflare называет инженера Google Дэвида Бенджамина. А чтобы через десять лет не застрять так же на TLS 1.4, тот же Бенджамин описал механизм GREASE (RFC 8701): Chrome нарочно добавляет в своё приветствие случайные зарезервированные значения вроде 0a0a, которые ничего не значат. Сервер или фильтр, который спотыкается о незнакомые значения, ломается сразу на них, и производитель вынужден исправить его, пока это дёшево.

Проще говоря: байты 16 03 03 — это обязательная подпись «здесь TLS», которую протокол оставил одинаковой ради старого оборудования. Именно её постоянство и использует ТСПУ: чтобы понять, что с запрещённого адреса пришёл TLS, ему не нужно знать версию и имя сервера, достаточно первых трёх байтов. Поэтому окно в 2 байта, о котором речь пойдёт ниже, и обманывает фильтр.

TLS 1.2 ещё нужен, и ему достаётся первым

В той же теме 23 октября прозвучало мнение, что TLS 1.2 скоро уберут из браузеров, поэтому новую проверку можно не замечать. Браузеры действительно давно используют TLS 1.3, но TLS 1.2 по-прежнему говорят многие программы и устройства. Системная библиотека TLS в Windows, на которой работают встроенные программы и часть сторонних, поддерживает TLS 1.3 начиная с Windows 11 и Windows Server 2022, а на Windows 10 включать его Microsoft не советует. К ним добавляются старые телевизоры, приставки и телефоны с приложением YouTube.

Для таких устройств rkn-chan 24 октября описал отдельную трудность. Приложения YouTube обращаются к API по имени youtubei.googleapis.com, и, по наблюдению участника, фильтр реагирует на сочетания слов в имени. Маркер midsld в multisplit режет посередине домена второго уровня, то есть внутри googleapis, а слово youtube в начале имени остаётся целым. У видеоузлов вида rr1---sn-….googlevideo.com всё наоборот: начало имени занято номером узла, и разрез в начале имени не задевает слово googlevideo. Чтобы одна стратегия покрыла оба случая, нужно минимум два разреза. Участник предложил написать для Zapret 2 функцию на Lua, которая сама находит в приветствии слова youtube и googlevideo и режет ровно по ним одним разрезом. На 31 октября 2026 года это идея, а не готовая функция.

Какие узлы googlevideo пропали

24 октября участник easyone11 написал, что у него перестали открываться два узла, rr4---sn-4g5lznl6.googlevideo.com и rr5---sn-5hne6nz6.googlevideo.com, а остальные работают. В тот же день spv82 проверил ещё десяток зарубежных узлов. Часть открывалась через Zapret 2 напрямую, часть не открывалась или работала нестабильно, но все работали через VPN. Российские узлы, наоборот, работали через Zapret и не открывались через несколько разных VPN: это ожидаемо, российские кэши часто не отвечают иностранным адресам, подробности в заметке о кэшах Google.

УзелАдресГруппа серверов Google (обратная запись DNS)ГородЧерез Zapret 2 24 октября
rr1---sn-f5f7lnly74.125.153.230waw02s29Варшаваоткрывается
rr1---sn-4g5ednre173.194.6.166fra16s81Франкфуртоткрывается
rr1---sn-4g5lznlr173.194.16.166fra24s28Франкфуртоткрывается
rr1---sn-u15hn5-5874.125.8.65tzamsa-avАмстердамоткрывается
rr1---sn-i5heen7s74.125.110.38ham11s03Гамбургнет или нестабильно
rr1---sn-i5heen7z74.125.13.70ham11s04Гамбургнет или нестабильно
rr2---sn-f5f7lnl774.125.104.167waw02s20Варшаванет или нестабильно
rr2---sn-4g5lznl774.125.163.167fra24s20Франкфуртнет или нестабильно
rr1---sn-4g5lznl674.125.173.38fra24s25Франкфуртнет или нестабильно
rr1---sn-5hne6nz674.125.100.198ams15s45Амстердамнет или нестабильно

31 октября 2026 года все эти имена по-прежнему указывали на те же адреса, а все адреса принадлежат Google: блоки 74.125.0.0/16 и 173.194.0.0/16 записаны в реестре ARIN за компанией (запись для 74.125.110.38). Группа серверов и город взяты из обратной записи DNS каждого адреса, о ней — в следующем разделе; города совпали с подсчётом участника spv82. В обсуждении фигурировали и «несуществующие» имена rr2---sn-isheen7s и rr5---sn-isheen7z, которых не было в DNS. Это опечатка, цифра 5 прочитана как буква s: имена rr2---sn-i5heen7s и rr5---sn-i5heen7z 31 октября давали ровно те адреса, что были указаны рядом, 74.125.110.39 и 74.125.13.74.

Где на самом деле проходит граница: группы серверов Google

Участники говорили о «проблемных подсетях», то есть о блоках из 256 адресов вида 74.125.110.0/24. Но у Google такой блок не однороден. У каждого адреса Google есть обратная запись DNS: имя, которое возвращается на запрос «чей это адрес». Все такие имена лежат в домене 1e100.net, который Google держит именно для этого. Для 74.125.110.38 обратная запись ham11s03-in-f6.1e100.net: первые буквы — код ближайшего аэропорта (ham — Гамбург), дальше номер площадки и номер группы серверов s03.

Если запросить обратные записи для всех 256 адресов подсети 74.125.110.0/24, она распадается на семь групп по 32 адреса (последняя на 64) в пяти городах: Гамбург (ham02, ham11s03), София (sof02s30), Франкфурт (fra16), Стокгольм (arn11, arn09) и Москва (svo07, по коду аэропорта Шереметьево). Недоступный адрес .38 лежит в гамбургской группе ham11s03, а «рабочий сосед» .70 — в софийской sof02s30. Это не соседние серверы одной площадки, а машины в разных странах, которым Google выдал адреса из одного блока.

Та же картина в остальных подсетях из таблицы. В Варшаве группа waw02s20 не работала, а waw02s29 работала. Во Франкфурте не работали fra24s20 и fra24s25, а fra24s28 и fra16s81 работали. Значит, фильтр не закрывает ни подсеть целиком, ни город, ни Google вообще: в его списке отдельные группы серверов размером в 32 адреса или отдельные адреса внутри них. Чтобы отличить одно от другого, нужно проверить из России несколько адресов одной группы; в обсуждении на 31 октября такой проверки нет.

Проще говоря: «18 рабочих адресов в той же подсети» — это не исключения внутри заблокированного блока, а серверы Google в других городах, которые просто не попали в список.

Почему в список попали именно эти группы, по открытым данным не видно. 31 октября 2026 года ни один из двенадцати адресов, рабочих и нерабочих, не значился в выгрузках реестра Роскомнадзора, которые публикует antifilter (списки allyouneed, ip, subnet и community), и сервис cheburcheck тоже не числил их заблокированными. Его зонды в 35–36 российских сетях 31 октября одинаково отвечали ok и для 74.125.110.38, и для 74.125.110.70. Это не опровергает блокировку: для адреса cheburcheck проверяет, доходят ли пакеты и где на пути стоит фильтр, но не ведёт рукопожатие TLS с самим адресом, поэтому фильтр, который режет только ответ TLS, ему не виден. Зато видно другое: полной блокировки по адресу, при которой не проходят даже пакеты установки соединения, у этих адресов нет. Это согласуется с тем, что нашли участники: соединение открывается, а гибнет ответ сервера.

Дело не в имени

Первая проверка, которая это показала, была сделана тоже 24 октября. Участник подключился к недоступному узлу, но назвал в запросе другое имя, из домена google.com, которое блокировать незачем:

curl --connect-to ::rr4---sn-4g5lznl6.googlevideo.com -Iv https://rr4---sn-4g5lznl6.c.docs.google.com

Соединение всё равно не прошло, и wssize в первых пробах тоже не помог. Из этого spv82 сделал вывод, что блокируется сочетание адреса и протокола TLS или вообще любые данные по TCP к этому адресу. 25 октября TesterTi сообщил, что у него перестала помогать и связка multisplit с wssize, работавшая накануне, а easyone11 — что у знакомого на Ростелекоме тоже пропала часть серверов, то есть дело не в одном провайдере.

Списки по сотне узлов

25 октября участники стали проверять узлы скриптом по списку. По подписям в теме, в списке было 116 узлов, а результаты сильно расходились: у exz в среднем 77 доступных, у byebye за пять запусков подряд 3, 46, 59, 61 и 58, у V3nilla на Ростелекоме в Приволжском федеральном округе 21. Разброс между запусками у одного человека говорит о том, что проверка ловит и нестабильность, а не только постоянную блокировку. В исправленном варианте скрипта, который проверяет именно HTTP/3, у SeamniZ вышло 76 из 109.

Первый вариант скрипта мог давать ложные результаты: системный curl.exe в Windows не умеет HTTP/3 и молча откатывался на TCP, а длинный список упирался в лимит длины командной строки. SeamniZ переделал его с помощью нейросети Claude и выложил список изменений: принудительный HTTP/3 через --http3-only, проверка, что сборка curl поддерживает HTTP/3 (такая есть на curl.se/windows), подача адресов через временный файл настроек и тайм-аут 3 секунды вместо одной, которая давала много ложных NOT WORKING.

Результат исправленного скрипта у SeamniZ: yt4.ggpht.com (сервер картинок YouTube) ответил по HTTP/3, а четыре узла googlevideo из конца списка не ответили, всего 76 доступных из 109. Сам автор оговорился, что в его списке нет узлов Ростелекома на IPv6 и не хватает многих российских кэшей, поэтому для российских сетей это скорее пример проверки, чем мерило.

Отдельно обсуждали QUIC, протокол поверх UDP, на котором работает HTTP/3. По трассировке участника TheyTookMyName с домашнего интернета МегаФона в Центральном федеральном округе, пакеты к любому *.googlevideo.com по UDP на порт 443 обрываются на ТСПУ. Выключен ли QUIC на самих узлах, участники так и не выяснили: один получил из Европы по HTTP/3 ответ 404 от rr1---sn-4g5lznl7.googlevideo.com, у другого тот же запрос curl --http3-only закончился тайм-аутом через 5 секунд. Что делать, если сайт виснет из-за блокировки QUIC, описано в заметке об отключении QUIC в браузере.

Механизм: «запретить TLS с адреса» и TCP-окно

29 октября rkn-chan показал проверку, которая отделяет адрес от имени полностью: подключиться к узлу Google, но попросить в запросе example.com.

curl -4v --connect-to ::74.125.110.38:443 https://example.com

С адреса 74.125.110.38 не проходит никакой TLS. Blockcheck, программа из комплекта zapret, которая перебирает стратегии, не нашёл ни одной рабочей. По словам rkn-chan, причина в том, что blockcheck не проверяет, подтвердил ли сервер получение приветствия. А обход есть: после того как приветствие клиента проходит, фильтр начинает смотреть ответ сервера, и это происходит даже в TLS 1.3, где имени в ответе нет вовсе.

Что такое TCP-окно

Чтобы понять, чем этот фильтр обходится, нужно одно понятие из устройства TCP. Каждая сторона соединения постоянно сообщает другой, сколько ещё байтов готова принять, пока не подтвердит уже полученное. Это число называется окном приёма (window size). Сервер не имеет права отправить больше, чем разрешает окно клиента, и ждёт подтверждения, прежде чем слать дальше.

Поле окна в заголовке TCP занимает 16 бит, то есть не больше 65 535 байт. Для быстрых каналов этого мало, поэтому в начале соединения стороны договариваются о множителе. Клиент сообщает степень двойки (scale), и дальше каждое значение окна умножается на 2 в этой степени. Множитель передаётся только в первом пакете соединения и фиксируется в каждом направлении при открытии соединения, позже его не изменить.

Функция wssize в zapret подменяет окно и множитель в исходящих пакетах клиента. Сервер видит «я могу принять всего пару байтов» и вынужден отдавать ответ крошечными порциями. В Zapret 2 это функция wssize в zapret-antidpi.lua с параметрами wsize (окно) и scale (множитель).

Почему проходит окно в 2 байта

rkn-chan обнаружил, что «проблемные» адреса пропускают TLS 1.3 при очень маленьком окне, wsize=1:scale=1: окно 1, умноженное на 2, то есть 2 байта. Никто бы не стал так обходить TLS 1.3, потому что в ответе сервера нечего прятать, но это работает. Сам участник предположил, что фильтру не нравится уже начало записи TLS, и называл возможный шаблон 16030300. Другие версии, которые он перебирал, — ошибка в фильтре или правило уровня TCP, чувствительное к границам пакетов.

Разработчик zapret bolvan подтвердил наблюдение на том же адресе и уточнил механику. Без wssize 1:0 или 1:1 соединение проходит нестабильно, и с окном от 3 байт тоже нестабильно. По его объяснению, дело не в том, на какие куски сервер режет ответ: сервер на Linux всё равно отправляет данные порциями больше двух байтов, а система клиента их принимает, потому что настоящее окно у неё гораздо больше. Дело в том, что фильтр учитывает объявленное окно и не разбирает то, что за него выходит. В двух байтах он не может узнать подпись TLS, для которой нужно хотя бы три.

Проще говоря: фильтр смотрит только на ту часть ответа сервера, которую клиент якобы готов принять. Если клиент «готов принять» два байта, фильтр видит 16 03 и не может решить, TLS это или нет, а потому пропускает.

bolvan связал это с привычками оборудования РДП.РУ (его платформа EcoDPI стоит в основе ТСПУ). По его словам, смотреть ServerHello — обычное поведение этого DPI. Если задача звучит как «запретить TLS с имени из списка, остальное пропустить», фильтр ищет имя сначала в приветствии клиента, затем в ответе сервера, и если не нашёл, пропускает. Если же задача «запретить TLS с адреса», ему достаточно убедиться, что это TLS, и проверяет он это самым простым способом, но только в пределах окна. Это объяснение специалиста, который много лет обходит этот DPI, а не описание из документации производителя.

Цена wssize 1:1: скорость падает в десятки раз

У приёма есть серьёзный недостаток, который bolvan разобрал в ответ на вопрос, нельзя ли просто включить wssize 1:1 для проблемных подсетей через ipset. Система клиента ничего не знает о подмене. Допустим, она открыла соединение с множителем 2⁷ = 128 и дальше указывает окно в расчёте на этот множитель. Zapret сообщил серверу множитель 2¹ = 2, и сервер честно умножает на 2. Окно, которое система задумала как 256 КБ, для сервера становится 4 КБ, в 64 раза меньше. Множитель изменить нельзя, поэтому окно остаётся маленьким и после того, как Zapret перестаёт трогать пакеты соединения.

С маленьким окном скорость упирается в задержку: сервер отправляет 4 КБ и ждёт подтверждения, которое возвращается через время «туда и обратно» (пинг). Верхняя граница скорости одного соединения равна окну, делённому на это время.

При пинге 10 мс потолок около 3,3 Мбит/с, при 20 мс около 1,6 Мбит/с, при 40 мс около 0,8 Мбит/с. Для сравнения, YouTube советует постоянную скорость 2,5 Мбит/с для 720p и 5 Мбит/с для 1080p. Без wssize то же соединение с окном 256 КБ при пинге 40 мс могло бы разогнаться примерно до 52 Мбит/с. Цифры на диаграмме посчитаны для одного соединения без потерь пакетов на примере окна из объяснения bolvan; в жизни окно и пинг другие, но порядок проигрыша тот же. Отсюда его вывод: если wssize 1:1 попадает на кэш Google, о видео высокого разрешения можно забыть, если только кэш не стоит очень близко.

Исправить это можно, если Zapret будет до конца соединения умножать окно в каждом исходящем пакете на 64 (и ставить 65 535, если выходит больше). Но тогда придётся перехватывать все пакеты соединения, включая пустые подтверждения, и процессор становится узким местом. По опыту bolvan, на процессоре уровня Intel Core i7-12700K это около 600 Мбит/с при одном полностью загруженном ядре, а на слабом роутере скорость может упасть до 10 Мбит/с. Пока такой режим не сделан, wssize 1:1 годится только как узкая мера для отдельных адресов через ipset: функция срабатывает в момент открытия соединения, когда имени сайта ещё нет, поэтому ограничить её списком доменов нельзя. Почему это так, подробно описано в заметке о wssize.

Участник wigeance напомнил, что приём не новый: во времена первой версии zapret, когда замедляли Telegram, через IPv6 он был закрыт полностью, а wssize 1:1 пропускал соединение.

Обходные пути: адреса вместо стратегии

Второй путь, который нашёл rkn-chan, связан с тем, что под фильтр попадает не вся подсеть. В подсети адреса 74.125.110.38 он нашёл 18 адресов, с которых TLS проходит, например 74.125.110.70. Как показано выше в разделе о группах серверов, это не соседи гамбургского сервера, а серверы Google в Софии, Франкфурте, Стокгольме и Москве. Если подключиться к такому адресу с именем недоступного узла, соединение работает с обычной стратегией без wssize:

curl -4v --connect-to ::74.125.110.70:443 https://rr1---sn-i5heen7s.googlevideo.com

Значит, можно прописать в файле hosts рабочий адрес для имени недоступного узла. По сути это просьба отдать видео с другой площадки Google, а не обход внутри того же сервера: имя rr1---sn-i5heen7s.googlevideo.com принадлежит гамбургской группе, а отвечать будет софийская. Сервер Google принимает такое имя, но будет ли он так же отдавать сам ролик и не окажется ли он дальше и медленнее, участники не проверяли. Сам автор называет оба пути «поиском иголки в стоге сена». Проблемные группы серверов нужно выявлять по одной и добавлять в ipset для wssize, а подмену в hosts придётся постоянно поддерживать: плеер раздаёт разные узлы, у разных кэшей рабочими оказываются разные адреса, и рано или поздно файл превратится в свалку. Такую подмену можно автоматизировать скриптом, но это хрупкая конструкция: если Google переселит узел, запись в hosts молча уведёт на чужой сервер.

Кроме этих двух путей, в теме выкладывали наборы стратегий с wssize:wsize=1:scale=6 и разными вариантами multidisorder, fake и multisplit с seqovl, а также сообщали о сайте, где сработал только tcpseg с pos=0,1. Это наборы для перебора на своём канале, а не проверенные рецепты: на разных провайдерах результаты расходились.

Память на 10 минут и идея с повторным SYN

29 октября участник Pavel4e5 предложил способ обойтись без постоянного wssize. Открыть соединение с маленьким окном, дождаться, пока пройдут приветствие клиента и начало ответа сервера, оборвать соединение с сервером и тут же открыть его заново с тем же портом клиента, но уже без wssize. Фильтр и клиент видели бы одно соединение, а сервер — два, и второе работало бы на полной скорости. Условие одно: фильтр должен отслеживать соединение только по пятёрке «адрес и порт клиента, адрес и порт сервера, протокол», не обращая внимания на флаги начала и конца соединения.

По словам Pavel4e5, на *.googlevideo.com у Ростелекома и у екатеринбургского провайдера «Планета» фильтр именно такой. Проверка: с включённым Zapret сделать запрос с фиксированного порта (curl --local-port 40000 https://rr1---sn-….googlevideo.com), дождаться, пока система освободит порт (около двух минут), выключить Zapret и повторить запрос с того же порта. Если фильтр такой, запрос пройдёт без всякого обхода. Автор называет срок памяти около 10 минут; столько же длится и блокировка этой пятёрки, если соединение не прошло. Поддельный RST, пакет экстренного разрыва соединения, фильтр не сбрасывает.

bolvan проверил это своим скриптом с паузой в 5 секунд между запросами. На googlevideo у двух провайдеров эффект подтвердился, а на meduza.io (за Cloudflare) и bbc.com второй запрос не прошёл. Его вывод — для Google сделали что-то особенное. Проверить HTTPS на кэшах Google у него не вышло, потому что HTTP на них вообще не блокируется.

Для самой идеи bolvan назвал два препятствия. Первое: фильтр защищён от трюков с RST, и если после RST приходит пакет с данными, фильтр заводит новую запись о соединении. Второе — устройство самого Zapret 2. Его собственный учёт соединений обрабатывает пакеты раньше Lua, и новый SYN на уже установленном соединении стирает запись вместе с состоянием Lua-функций. Чтобы реализовать идею, пришлось бы отключить этот учёт и переписать логику на Lua или хранить состояние переходов в глобальных переменных Lua. На 31 октября 2026 года это обсуждение, а не готовая стратегия.

Тот же учёт окна в другом месте: dns.nextdns.io

30 октября участник tehkos разбирался с dns.nextdns.io, сервером DNS поверх HTTPS. Стратегия с поддельным приветствием работала, если фильтровать трафик по порту и протоколу. Но стоило добавить список доменов --hostlist-domains=dns.nextdns.io, как она переставала работать для TLS 1.3, хотя для TLS 1.2 работала. В подробном журнале Zapret 2 нашлась строка:

reasm cancelled because server window size 1448 is smaller than expected reasm size 1542

Она выводится в desync.c Zapret 2, когда сборка приветствия из нескольких TCP-пакетов отменяется. bolvan объяснил, что происходит. Сервер NextDNS защищается от DDoS-атак и в начале соединения даёт клиенту окно всего 1 448 байт. Приветствие TLS 1.2 короткое и помещается в один пакет. Приветствие TLS 1.3 содержит открытый ключ клиента (расширение key_share), и в современных клиентах оно длиннее окна: на снимке Wireshark у tehkos приветствие собиралось из двух пакетов, всего 1 542 байта. Zapret 2 в такой ситуации не может дождаться второго куска, отменяет сборку, чтобы соединение не зависло, и остаётся без имени сайта. По первому куску он узнаёт TLS, но не знает имени, а профиль со списком доменов при пустом имени сразу пропускается.

Снимок Wireshark, который tehkos выложил вместе с журналами, показывает это окно своими глазами. В строке 1 клиент открывает соединение с окном 64 240 байт и множителем 256 (WS=256). В строке 2 сервер отвечает Win=1448: столько клиент может отправить, не дожидаясь подтверждения. Строка 4 — первый кусок приветствия, 1 334 байта, строка 7 — второй кусок на 208 байт, который Wireshark уже подписывает как Client Hello (SNI=dns.nextdns.io); внизу справа видна сборка обоих кусков, Reassembled TCP (1542 bytes). Строки 8–10 — повторные отправки второго куска: подтверждения на него так и не пришло, и соединение встало. В разборе приветствия слева видно, что клиент предлагает и TLS 1.3, и TLS 1.2 (supported_versions).

Ключ раздувается из-за постквантовой криптографии. С Chrome 131 браузер по умолчанию предлагает гибридный обмен ключами X25519 с ML-KEM (стандартизированная версия алгоритма Kyber; на форуме его зовут «кибером»), и только эта часть ключа занимает больше килобайта. Тот же эффект виден и в замере для этой заметки: Python 3 с OpenSSL 3.5.6 прислал приветствие TLS 1.3 на 1 502 байта против 233 байт у TLS 1.2.

Добавили этот ключ не ради красоты. Google объяснил переход угрозой «собери сейчас, расшифруй потом»: записанный сегодня трафик можно будет расшифровать через годы, если появится достаточно мощный квантовый компьютер, а классический обмен ключами X25519 перед ним беззащитен. Гибрид X25519 с ML-KEM остаётся не слабее классики, даже если новый алгоритм окажется с изъяном. Цену Google назвал там же: приветствие вырастает больше чем на килобайт, и в пробах часть сетевых устройств ломалась на жёстко зашитом ограничении размера. Сайт tldr.fail, который ведут для таких случаев, прямо пишет, что постквантовое приветствие больше не помещается в один пакет. Учёт окна в ТСПУ и отмена сборки в Zapret 2 у NextDNS — та же болезнь роста: и фильтр, и обход писались в расчёте на приветствие в одном пакете.

Решение bolvan простое: если клиент не трогать, отказаться от списка доменов и отбирать трафик к этому серверу по адресу через ipset, потому что адрес известен с первого пакета. Подробнее о том, как профиль выбирается по спискам, — в заметке о фильтрах профиля. У SeamniZ одна конкретная ссылка NextDNS не заработала и так. spv82 ответил, что для этого сервера достаточно multidisorder с pos=1. bolvan добавил, что без сборки приветствия маркеры разреза multisplit могут не сработать, если нужной части нет в первом куске, а поддельный пакет fake обычно отправляется до первого пакета и от этого не страдает.

Последнее сообщение bolvan 31 октября связало обе истории. Фильтр отслеживает окно и в эту сторону: если поддельное приветствие длиннее окна, которое сервер дал клиенту, фильтр обрезает его по окну, не может достать оттуда имя и не «успокаивается». SeamniZ помогло убрать из поддельного приветствия постквантовый ключ: оно укоротилось и влезло в окно 1 448 байт. Создавать собственные поддельные приветствия в Zapret 2 позволяют блобы.

Сама блокировка NextDNS, которая к 31 октября 2026 года охватила почти все проверенные российские сети, разобрана в отдельной заметке: там записи трафика, проверка cheburcheck и рабочие стратегии.

Что делать на 31 октября 2026

Если YouTube грузит видео рывками, а отдельные ролики не стартуют, сначала стоит понять, к какому узлу идёт плеер. Адрес узла виден в инструментах разработчика браузера (вкладка «Сеть», запросы videoplayback). Дальше по шагам:

  • Проверить, отвечает ли адрес узла на TLS с посторонним именем: curl -4v --connect-to ::<адрес>:443 https://example.com. Если не отвечает, а через VPN тот же узел открывается, это фильтр по адресу, и перебор обычных стратегий по имени не поможет.
  • Не включать wssize 1:1 для всего порта 443. Если без него никак, ограничить его адресами попавших под фильтр групп серверов через ipset (блоки по 32 адреса; границы группы видны по обратной записи DNS, команда nslookup <адрес>) и помнить, что видео с этих адресов пойдёт медленно.
  • Для старых устройств и программ на TLS 1.2 ждать, что фильтр проверит и ответ сервера; при мелкой нарезке приветствия это вероятнее.
  • Для серверов с маленьким начальным окном вроде dns.nextdns.io отбирать трафик по адресу, а не по списку доменов, и укоротить поддельное приветствие, если оно длиннее окна.
  • Не делать выводов по одному запуску скрипта проверки: у одного участника доступность одних и тех же узлов менялась от 3 до 61 из 116 подряд.

Почему «Запрет перестал работать» обычно означает перемену на стороне фильтра, а не поломку программы, разобрано в заметке о симптоме и причине; как проверять стратегию на своём канале — в отдельной инструкции.

Источники

📚 См. также


🤖 Эти статьи открыты — можно обучать на них ИИ

При желании вы можете натренировать ИИ на наших статьях. Исходное форматирование доступно в Forgejo: исходник этой заметки · скачать весь репозиторий одним zip-архивом.