Привет, Хабр!
В последнее время замечаю огромное количество информации по поводу замедления Великого, но очень мало где видел конкретику о том, как именно это работает. Одно лишь отчаяние "мы все умрём".
Сразу скажу, что буду говорить обо всём, что известно на данный момент. Понятно, что с этим разбирался далеко не один я: огромное спасибо обывателям ntc party форума за проделанный ресёрч.
В конце статьи есть информация об известных на данный момент способах обхода, а также список ресурсов, с помощью которых можно еще глубже копнуть в замедление.
UPD 10.08.2024 Многие жалуются на недоступность ютуба в целом: не грузит домашнюю страницу. Переживать не стоит, оно обрабатывается всё тем же ТСПУ по всё той же стратегии, обходы должны работать.
Так вот, начнём сначала, с злополучного GGC. Официальное заявление было, что кэш сервера устарели и долго не обновлялись, но у многих возникло такое скептическое чувство: "до этого работали, а тут в один момент всё поломалось". К тому же есть статья на википедии, которая утверждает, что разговоры про эти GGC шли еще с 2018 года. Да и если это были они, у нас бы плохо работала львиная доля гугл сервисов, включая Google Drive, Google PlayMarket, Google Images. А оно работает прекрасно, как и прежде.
UPD 02.08.2024: В Google подтвердили, что проблемы у российских пользователей не связаны с техническим состоянием оборудования компании. https://www.kommersant.ru/doc/6866088
Дальше рассмотрим идею, что это вообще гугл тестирует ограничение загрузчиков типа yt-dlp, потому что, в первую очередь, проблемы коснулись именно их. Идея на самом деле интересная, потому что действительно на современных протоколах (QUIC) всё хорошо работает, а проблемы есть только на старом добром TCP (сейчас ходят слухи, что и QUIC начали ограничивать, и, вроде как, я могу это подтвердить). Эту и предыдущую идеи мы опровергнем далее.
Как только я начал разбираться с этой проблемой и открыл Wireshark, меня ждали логи, состоящие наполовину из красных полос. Я не стал особо думать над тем, как именно замедляется ютуб со стороны TCP, но сразу стало понятно, что замедление искусственное, ��отому что если бы это были GGC, они бы либо не работали вообще, либо просто скорость была маленькая, а тут тонны потерянных пакетов. А еще забавно, что с QUIC, который автоматом работает в хроме такого вообще не происходило и скорость была в норме. Я начал искать и вспомнил про один очень крутой форум по обходу всяких подобных приколов с цензурой интернета, ntc party. Там я нашёл, как именно замедляется ютуб и контрпример, подтверждающий на 100%, что это проделки большого брата.
Но перед тем, как назвать способ замедления, давайте подумаем, а как они могут вообще определить, что я смотрю ютуб просто видя raw ip пакеты. Пойдём с самого низкого уровня, который может их заинтересовать, IP. Что тут есть? IP адрес. И это очень мощный инструмент, правда если их не тысячи, и если на них работает только один сервис, googlevideo. В случае огромной инфраструктуры гугла их банально сложно получить, я уже не говорю про то, что если на одном айпишнике работают, скажем гуглвидео и гугл плеймаркет, а ведь вероятность такая есть, это же GGC как никак. Тогда обрубая одно, обрубим и другое. Что делать? Посмотрим выше. На TCP мало чего интересного, поднимаемся еще выше. А дальше TLS. И это всё? Почти... Да, современные протоколы сделаны так, чтобы шифровать всё, что можно. Но есть только одно исключение. В спецификации TLS есть такая вещь, как SNI. Она передаётся серверу и говорит ему, к какому именно сайту мы хотим подключиться и, следовательно, какой именно сертификат нам давать. Что-то типа Host в HTTP, но для TLS. Так вот, этот самый SNI спокойно себе передаётся в незашифрованном виде. Было много спецификаций, предлагающих его зашифровать, но мэйнстримом оно не стало. К тому же, провайдеры блокировали такие подключения, чтобы не мешали следить за юзерами.
Так вот, SNI лежит в незашифрованном виде в Client Hello, и, обнаружив его, мы можем коннмарком пометить соединение и выкидывать рандомные пакеты.
Я знаю, что вы ждёте пруфов, господа, и вот они:
curl --connect-to ::speedtest.selectel.ru https://manifest.googlevideo.com/100MB -k -o/dev/null
Что мы видим в этом curl запросе? У curl'a есть возможность подключаться к серверу с его именем, но вместо резолвинга DNS поставить какой-нибудь свой айпи. При этом вся информация более высокого уровня будет передаваться, как будто мы используем именно это имя. Такое поведение заставляет curl подменять тот самый SNI (ну еще и Host, но это нас не особенно интересует). -k флаг используется, чтобы отключить проверку сертификатов (она провалится, потому что speedtest.selectel.ru будет нам давать свой сертификат, но никак не желаемый от гуглвидео). И если запустить это запрос, то мы получим весёлую скорость в 120 килобайт на начале, и дальше она пойдёт на спад. Даже до нуля может дойти. А теперь замените любую букву в googlevideo на другую и скорость прыгнет до нормальной скорости интернета. Всё стало на свои места.
Как с этим бороться?
Конечно, способы борьбы существуют. Для этого будем думать в сторону манглинга (изменения) пакетов. Но если мы просто заменим googlevideo.com на yandex.ru, получим ошибку сертификатов. И не факт что браузер вообще позволит отключить эту проверку для гуглвидео и нормально будет с этим жить. Так что же делать?
Вспомнить про то, что ТСПУ - это всё-таки очень высоконагруженная штука, которая вряд ли будет запоминать, что и когда мы там отправляли в сеть, и, соответственно, если мы просто разобьем наш запрос на два в середине SNI, то О Чудо! Всё начинает работать. В моём случае не понадобились даже фейковые Client Hello или задержка между пакетами (но вроде как ему всё-таки нужен обратный порядок пакетов: сначала идёт хвост, потом голова).
UPD: От 01.08.2024, видимо, обновили ТСПУ на некоторых провайдерах и теперь фейковый ClientHello стал обязательным. Фейковый ClientHello - это Out-of-seq, out-of-ack TCP пакет. Он считывается и обрабатывается ТСПУ, но конечный ресурс его отбрасывает (Invalid state в conntrack).
Как разбивать? Есть два варианта: фрагментами IP и на уровне сегментации TCP. У меня лично фрагментация IP сначала работала на половину, а потом и вообще отвалилась. Возможно, провайдеру не понравилось. Идём выше, к TCP. И тут у них всё очень приятно работает. Даже несмотря на то, что я, казалось бы, из одного пакета сделал два, поменяв размеры двух пакетов, я не нарушил никаких правил TCP соединения: Ack по количеству доставленных байт - вещь.
Готовые средства обхода. Ну и самое вкусненькое. Я лично написал своё решение под линукс и роутеры на базе OpenWRT, которое направлено только на ютуб. Для Windows существует GoodbyeDPI от ValdikSS, под линукс еще есть zapret. Существует ByeDPI, который работает как прокси (Windows/Linux). Также есть версия ByeDPI под андройд, работает как "фейковый впн". Советую прочитать подробный комментарий от ValdikSS о том, как использовать эти средства. Если есть желание погрузиться глубже в эту тему, тут можно посмотреть подробнее: https://ntc.party/t/замедление-youtube-в-россии/8055/ и https://ntc.party/t/обсуждение-замедление-youtube-в-россии/8074/