Привет, Хабр!
В последнее время замечаю огромное количество информации по поводу замедления Великого, но очень мало где видел конкретику о том, как именно это работает. Одно лишь отчаяние "мы все умрём".
Сразу скажу, что буду говорить обо всём, что известно на данный момент. Понятно, что с этим разбирался далеко не один я: огромное спасибо обывателям 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/