惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
爱范儿
爱范儿
GbyAI
GbyAI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
Y
Y Combinator Blog
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
M
MIT News - Artificial intelligence
博客园 - Franky
V
Visual Studio Blog
I
InfoQ
V
V2EX
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
博客园 - 司徒正美
L
LangChain Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания
MTProxy jumper — делаем автоматическое переключение прокс...
Bóbr Kurwa · 2026-05-25 · via Все публикации подряд на Хабре

Средний

7 мин

31K

В свете последних новостей вокруг Telegram провела некоторые эксперименты с протоколом MTProxy.

Основная идея: сделать ПО, выглядящее для Telegram-клиента как MTProxy-сервер, и осуществляющее дальнейший обмен данными со сторонними MTProxy-серверами.

В идеале, эти сторонние серверы должны обнаруживаться автоматически, и переключение между ними тоже должно происходить автоматически.


Постановка задачи

Код пишется на Python. Как экспериментальный вариант для быстрой реализации сойдёт, а если ПО окажется востребованным, то можно будет переписать на Си.

От протокола MTProxy реализуется только та часть, которая относится к соединениям, имитирующим TLS (FakeTLS, ключ прокси начинается с “ee”). Другие виды соединений кажутся более уязвимыми к DPI-вредительству, и оттого не очень полезными.

Предполагается, что ПО запускается на компьютере. Проверка работоспособности осуществляется в клиентах Telegram Desktop и Unigram под Windows.

С точки зрения клиента ПО выглядит как обычный MTProxy-сервер, подключение осуществляется штатным способом. Приняв соединение от клиента, ПО тут же пытается установить соединение со сторонним MTProxy-сервером. Если это удалось, то далее ПО все приходящие от клиента данные пересылает на сторонний сервер и наоборот, все приходящие от стороннего сервера данные пересылает на клиент. При этом происходит перекодирование, так как протокол шифрованный.

Если установить соединение со сторонним сервером не удалось, либо если соединение прервалось, соединение с клиентом тут же закрывается. Ожидаем, что обнаружив это, клиент Telegram пробует пересоединиться с нашим ПО, и всё повторяется.

Сторонний MTProxy-сервер выбирается как один из списка. Этот список может быть либо задан заранее, либо скачиваться с заданного URL.

Тестовый стенд

Для экспериментов был нужен заведомо работающий прокси. Самый надёжный вариант — развернуть его на своей же машине. Был взят mtg (https://github.com/9seconds/mtg), который запускался через mtg run config.toml, а конфигурационный файл config.toml был копией example.config.toml с минимальными изменениями:

secret = "ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d"
bind-to = "127.0.0.1:3128"

[network]
proxies = [
    "socks5://127.0.0.1:9150"
]

[defense.blocklist]
enabled = false

В такой конфигурации mtg принимает соединения на порту 3128 по протоколу MTProxy и обеспечивает обмен с серверами Telegram через SOCKS5-прокси на порту 9150.

Висящий запущенным Tor Browser как раз поднимает SOCKS5-прокси на порту 9150, которое может использоваться и другими приложениями. В нашем случае он нужен для обеспечения надёжной связи с серверами Telegram в обстановке DPI-вредительства.

О ключах прокси

Ключи прокси бывают:

  • “простые” — 32 шестнадцатеричных цифры ключа (т.е. 16 байтов)

  • “dd” — сначала буквы “dd”, далее 32 шестнадцатеричных цифры ключа

  • “ee” — сначала буквы “ee”, далее 32 шестнадцатеричных цифры ключа, далее закодированное в шестнадцатеричном виде имитируемое доменное имя (Telegram Desktop хочет, чтобы в нём было не менее четырёх букв после раскодирования)

  • “странные” — формат не соответствует ни одному из вышеперечисленных

При соединении клиент выбирает используемый протокол в зависимости от вида ключа. Ключи “ee” соответствуют протоколу с использованием FakeTLS. Исключительно им мы и уделим внимание.

Остальные виды ключей соответствуют “голому” протоколу MTProxy, без обёртки в TLS. Формат “dd” предполагает обфускацию, но, говорят, сейчас это не очень работоспособно. Со “странными” форматами я не разбиралась, там бывает что-то похожее на Base64. Протокол, по-видимому, тоже “голый”.

Несмотря на сомнения, отметим, что, не-“ee” ключи довольно распространены. При парсинге одного из списков прокси из 125 записей обнаружилось: “простых” - 16, “dd” - 29, “ee” - 34, “странных” - 46. Наводит на мысли, что раз их делают, то какой-то смысл в них, возможно, есть.

О протоколе MTProxy с FakeTLS

Документация от разработчиков Telegram вызывает печаль, поэтому, возможно, этот параграф стоило бы развернуть в отдельную статью. Пока же кратко об основных принципах.

В варианте с FakeTLS протокол MTProxy мимикрирует под HTTPS (HTTP/2 через TLS 1.2).

  • Клиент посылает TLS-пакет Client Hello. По сути, важны там только поле Random и расширение server_name. Random используется для хранения дайджеста, вычисляемого на основе содержимого пакета, 16-байтного ключа прокси и текущего времени. Сервер проверяет его соответствие. server_name содержит имитируемое доменное имя, и сервер может сверить его соответствие тому, что указано в текстовом представлении ключа (хотя особого смысла в этой сверке нету).

  • Прокси-сервер посылает сразу три TLS-пакета: Server Hello, Change Cipher Spec, Application Data. Тут важно поле Random, используемое для хранения дайджеста, вычисляемого на основе содержимого всех трёх пакетов, а также дайджеста из пакета Client Hello. Не очень понятно, почему для вычисления используется не только Server Hello, а все три пакета. Также не ясно, всегда ли их обязано быть именно три и именно таких.

  • Далее клиент и сервер условно-бесконечно гоняют туда-сюда пакеты Application Data и Change Cipher Spec. В первый оборачиваются данные “голого” протокола MTProxy, второй, по-видимому, просто игнорируется.

Пример Client Hello

Пример Client Hello

Пример Server Hello

Пример Server Hello

Содержимое первого пакета Application Data (который приходит совместно с Server Hello) игнорируется. Во втором пакете Application Data первые 64 байта совместно с 16-байтным ключом прокси используются для генерации ключей, используемых для шифрования остатков второго пакета, а также содержимого всех последующих пакетов Application Data.

Принцип работы ПО

ПО выступает в роли посредника между клиентом Telegram и сторонним MTProxy-сервером. Таким образом, дя клиента оно выглядит как MTProxy-сервер, а для стороннего сервера — как клиент.

ПО ожидает входящие соединения от клиента. Для каждого принятого соединения:

  • от клиента принимается пакет Client Hello, осуществляется его валидация

  • в пакете заменяется поле расширения server_name, пересчитывается поле Random

  • устанавливается соединение со сторонним прокси-сервером (про принцип выбора из списка - см. ниже)

  • изменённый пакет Client Hello отправляется серверу

  • от сервера принимается пакет Server Hello (плюс ещё два - см. предыдущий параграф), осуществляется его валидация

  • в пакете пересчитывается поле Random

  • изменённый пакет Server Hello (плюс ещё два) отправляется клиенту

  • далее в цикле, в направлениях от клиента к серверу и от сервера к клиенту пересылаются пакеты Application Data и Change Cipher Spec - Change Cipher Spec напрямую, Application Data после расшифрования и последующего зашифрования нужным ключом

  • при обрыве соединения с сервером, либо при получении невалидных данных соединения с клиентом и с сервером разрываются; предполагается, что в этом случае клиент повторит попытку установки соединения

Выбор прокси из списка

Простейший алгоритм выбора прокси-сервера из имеющегося списка - просто выбирать следующий по списку, а когда список закончится, возвращаться в начало. На практике это не очень хорошо работает, т.к. в публичных списках работающими оказываются лишь немногие прокси, и при разрыве соединения пройдёт значительное время, пока будет идти перебор серверов.

На данный момент реализован следующий алгоритм. При получении от сервера валидного пакета Server Hello увеличивается на 1 счётчик для данного сервера. Когда устанавливается новое соединение с клиентом и требуется выбрать прокси-сервер из списка, берётся какой-то из серверов, имеющих положительное значение счётчика, а счётчик уменьшается на 1. Если нету ни одного положительного счётчика, сервер выбирается по простейшему алгоритму.

Такой алгоритм позволяет при случайном разрыве соединения пытаться установить соединение в первую очередь с теми серверами, с которыми уже случались успешные соединения.

О проблеме “fe02”

Про это уже много писали — статья на Хабре, pull request к официальному клиенту и commit с исправлением

Суть проблемы — в Client Hello хотели из клиента передавать расширение TLS encrypted_client_hello с кодом 0xfe0d, но из-за ошибки в коде передавали несуществующее 0xfe02, по которому злоумышленники и могли отследить, что это именно Telegram (см. выше на картинке среди обведённого).

В ПО добавила workaround для починки пакета. Однако, никакой разницы не обнаружила. Те серверы, которые блокировались по DPI (в логах это выглядит как разрыв соединения после отправки Client Hello на сервер), так и продолжили блокироваться. Видимо, в моём случае либо блокируется по IP, либо DPI реагирует на другие признаки. Тут можно продолжать эксперименты. Менять можно практически все поля, благо, для протокола MTProxy в Client Hello ничего, кроме поля Random, не важно.

Возможные проблемы

При использовании сторонних прокси-серверов возможны проблемы:

  • ненадёжность (и непредсказуемость) соединения

  • низкая (и непредсказуемая) скорость

  • утечка метаданных к владельцу стороннего сервера (хотя для самих сообщений обещают шифрование)

  • у прокси-серверов есть возможность принудительно добавлять “спонсорский канал”, а при автоматическом переключении прокси это ещё и происходит внезапно (но, хотя бы, их не будет более одного, т.к. при отключении от прокси соответствующий канал пропадает)

  • ну и звонки в Telegram ходят мимо прокси, поэтому если поломаны, то не починятся

Как это пощупать своими руками

Репозиторий проекта тут: https://codeberg.org/bokurwa/mtjumper-py.git

Нужен Python.

git clone https://codeberg.org/bokurwa/mtjumper-py.git
cd mtjumper-py
pip install pycryptodome
python mtjumper.py

Если заглянуть в исходники, то можно увидеть там такие строки, которые может оказаться полезным поменять:

OUR_CONFIG_URL = "tg://proxy?server=127.0.0.1&port=13128&type=mtproto&secret=ee0000000000000000000000000000000078787878"

TARGET_CONFIG_URLS = [
  "tg://proxy?server=127.0.0.1&port=3128&type=mtproto&secret=ee367a189aee18fa31c190054efd4a8e9573746f726167652e676f6f676c65617069732e636f6d",
  "@ https://raw.githubusercontent.com/SoliSpirit/mtproto/refs/heads/master/all_proxies.txt’,
]

OUR_CONFIG_URL — ссылка, которую можно открыть в Telegram, чтобы не вводить руками. Тут можно поменять порт, если не устраивает 13128, и адрес на 0.0.0.0, чтобы к нашему прокси можно было обращаться с других машин в локальной сети.

TARGET_CONFIG_URLS — список ссылок на прокси-серверы. Если в начале стоит @, то это ссылка для скачивания списка прокси (в текущей версии список скачивается только один раз при старте). По умолчанию там забиты URL тестового стенда и URL одного из списков прокси.

Литература

  1. Telegram научился маскироваться под HTTPS

  2. Исходники прокси от автора статьи [1]

  3. RFC 5246 — The Transport Layer Security (TLS) Protocol. Version 1.2

  4. RFC 6066 — Transport Layer Security (TLS) Extensions: Extension Definitions

  5. RFC 9849 — TLS Encrypted Client Hello

  6. MTProto transports