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

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
Y
Y Combinator Blog
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
S
SegmentFault 最新的问题
J
Java Code Geeks
V
Visual Studio Blog
H
Help Net Security
Stack Overflow Blog
Stack Overflow Blog
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - Franky
B
Blog RSS Feed
The Cloudflare Blog
MyScale Blog
MyScale Blog
月光博客
月光博客
Microsoft Security Blog
Microsoft Security 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