Комментарии 155
Этот пост так же хороший и приводит новые технические подробности.
PS: если я правильно понял, автор поста — автор прокси на Python который один из первых и добавил поддержку.
Да, всё так. Написал эту статью параллельно с добавлением поддержки, но, видя как авторы телеграм маскировали её в коммитах бета-версий, решил подождать релиза, чтобы не дать создателям средств DPI времени подготовиться.
Не планируете реализовать «слив» трафика с другим SNI на другой порт?
Т.е когда к вам идёт запрос не на домен который указан в прокси а на другой — показывать обычный сайт.
Как раз экспериментирую с этим.
Ну так со временем будет eSNI и это будет иметь смысл.
Но было бы гораздо практичнее, особенно для чайников, если бы это было реализовано на уровне прокси. Да и обнаружение было бы гораздо сложнее, сейчас оно всё-таки возможно, если система контроля активная и сама пощупает порт.
Нет нельзя, сейчас домен А может использоваться только: либо телеграм либо веб-сервер.
Доработке прокси позволит использовать один и тот же домен А и для прокси и для веб-сервер. Отправляя запросы на последний в случае ошибки в секрете.
Отправляя запросы на последний в случае ошибки в секрете.
Да, это наиболее верный подход, как по мне.
А на самом домене вешать уже нормальный сайт.
URL в TLS mtproto proxy протоколе не используется
Ну для этого придётся полноценный TLS реализовывать. То что в mtproto proxy — хоть и маскируется под TLS 1.3, но внутри совсем по другому устроено.
Зачем нужен mtproto proxy, который прямо таки кричит в любой DPI помощнее «вот он я, берите меня, unknown proto!» — тоже неясно.
mtproto proxy, который прямо таки кричит в любой DPI помощнее «вот он я, берите меня, unknown proto!»
Почему? DPI никакого URL внутри TLS не увидит, как и не увидит того, что они не используются. Максимум — SNI (так никто не мешает указывать реальный dyndns-хост). DPI видит, что «на хост ходят по TLS» и всё. Расшифровать содержимое оно не может, не зная секрета. Попробует зайти на хост само — получит страничку с котиками (если в проксе настроен проброс невалидных коннектов на реальный веб-сервер).
Где я ошибаюсь, полагая, что у DPI нет критериев для вынесения предположения о содержимом TLS1.3 сессии?
Зато увидит, что работающего TLS на втором конце нет.
Зато увидит, что работающего TLS на втором конце нет.
Я и прошу объяснить — КАК? По каким признакам?
Во-вторых, активный сканер может прикинуться телего-клиентом и найти проксю, если не использовать какие-то дополнительные признаки — eSNI заголовок или URL.
Активному сканеру, как и клиенту Telegram, нужно знать secret для того, чтобы подключиться к прокси-серверу
активный сканер может прикинуться телего-клиентом
Может прикинуться. Только он не знает секрета. «Ничего не ответил прокси, лишь хомпейдж Википедии выдал…»
Впрочем, я думаю, что и с ним можно, если речь именно о белом айпи, а не домене — средствами nginx. Но смысла лично я мало вижу, подожду решения с проверкой ключа.
И поэтому использование какого-то особого SNI — сразу палево, разве нет?
Нужен мультиплексор по ключу, как описано ниже. Если ключ подходит, то соединять с прокси, если нет, то передавать на веб-сервер, который может обрабатывать трафик как угодно, у него могут быть несколько виртуальных доменов даже.
Телеграм-клиенты при этом должны как раз корректный SNI использовать, чтобы внешне не отличаться от стандартных веб-клиентов.
Закончил экспериментировать и закоммитил эту функциональность. Сейчас можно указывать хост и порт на который будет незаметно проксироваться трафик "плохих" клиентов.
Попробую продемонстрировать как это работает:
- есть сайт который выглядит для браузера "обычно": https://bitblockinfo.com/
- в то же время он является замаскированным прокси сервером tg://proxy?server=bitblockinfo.com&port=443&secret=7gARIjNEVWZ3iJmqu8zd7v9iaXRibG9ja2luZm8uY29t.
Это сделано для того, чтобы нельзя было задетектить прокси-сервер по особенностям работы с TLS.
PS: мобильный Telegram (андроид) сходит с ума от сгенерированной и втянутой ссылки на прокси с более-менее длинным TLS_DOMAIN. И просто зависает.
Советую посмотреть это подробнее, вдруг там буфер переполняется и можно хакнуть.
Я обратил внимание, что сгенерированный секрет с доменом google.com не содержит в конце символа суффикса «=». И с ним моб.клиент работает. А вот с моим доменом секрет имеет в конце суффикс «=» — и клиент ломается. Криво декодируется base64 в клиенте?
С моим доменом секрет получается в таком виде:
7u***************wjjNQRnYXRlLmtueXNob3YuaW5mbw%3D%3D
Кстати, а можно попросить объяснить, на что влияет значение TLS_DOMAIN в текущей реализации? Особенно учитывая, что можно произвольно изменить несколько последних символов секрета уже прописывая его в клиенте и тебе ничего за это не будет?
Сейчас ни на что, кроме генерации ссылки в начале работы. Планирую его использовать на серверах с большим количеством секретов, чтобы по имени можно сразу было бы пробовать расшифровать с нужным секретом.
В ближайший час планирую поменять вывод адреса прокси по умолчанию, чтобы не использовалось base64 пока авторы Telegram не починят клиента для ios.
На практике проблемы производительности не возникает. Даже самой дешёвой виртуальной машины хватает чтобы обслужить несколько тысяч пользователей. Но столько пользователей набрать тяжело т.к. основные каналы распространения информации о прокси серверах мониторятся. При большом числе пользователей прокси сервер может быть заблокирован по паттернам трафика
У меня больше всего опыта работы с этим языком. Но есть и другие реализации разной степени продвинутости: на go, erlang, си, c#, nodejs, java, pony и т.д.
Если нужна производительность, то лучше выбрать официальную реализацию на си. Её код всё ещё приводит меня в восторг. Правда, они уже пол года ничего не коммитили.
он довольно новый
лол
https://en.wikipedia.org/wiki/Python_(programming_language)
First appeared 1990; 29 years ago
https://en.wikipedia.org/wiki/Node.js
Initial release May 27, 2009; 10 years ago
https://en.wikipedia.org/wiki/JavaScript
First appeared December 4, 1995; 23 years ago
Edit: добавил JS
2) «В некоторых областях» бывает всякое: и Free Pascal быстрее Си и C++, и Нода в пять раз медленее Питона, и PHP отстаёт от Go и C++ на смешные 7-15%.
3) Нода память жрёт как не в себя.
4) Js один из худших языков среди массовых.
На самом деле не хватает последнего шага:
- Возможность серверу определять домен по SNI и если домен не попадает в заданный список, то пропускать коннект дальше (на обычный web сервер с заглушкой).
- Возможность работы через WebSocket'ы, работая в качестве backend'а для обычного web server'а типа nginx, при этом добавив минимальную http basic аутентификацию.
Тогда прокси можно будет вешать на реальных живых сайтах, с реальным трафиком. Просто будет поддомен stat.mysite.ru или даже просто конкретный URL на сайте, закрытый http basic auth'ом.
Даже если "постучался" — тебя послали нафиг, а владелец сайта (ну если вдруг ему начнут задавать вопросы) честно скажет "это закрытый раздел сайта".
Ну а телега сможет сделать upgrade до вебсокетов и дальше кидать свой трафик, к примеру завернув туда тот самый mtproxy.
Тот же nginx в качестве фронтенда великолепно подойдёт.
И нет необходимости прикрываться именами типа google.com, наоборот веселее будет кому-то получить прокси на реальных серверах с реальным доменным именем типа bstat.gosuslugi.ru, закрывшись самым настоящим сертификатом *.gosuslugi.ru ;)))
Первый плюс — у себя сэкономим трафик и ресурсы.
Второе, — займем ресурсы проверяющего бота.
- Тут даже можно пойти дальше — сделать один домен и если HMAC из поля random handshake-пакета не валидный, то редиректить. Сегодня вечером будет версия, которая так делает.
- Насколько я понял, тут нужна поддержка со стороны фронта или клиента Telegram. Для себя можно поднимать веб-версии Telegram, но маловероятно, что сторонний человек согласиться ввести свои credentials на сайт, не связанный с тг.
Обязательно нужна поддержка со стороны клиентов, причём тех, которые лежат в google/apple market'ах.
Как минимум — возможность работы через WebSocket.
Но если это реализовать, то блокировать телегу можно будет только тем самым "законом о суверенном интернете" с полной изоляцией российского сегмента сети. И то не факт ;)
Вам никто не мешает использовать не родной клиент или официальную веб-версию.
Место действия Казахстан.
У меня, фильтруются всякие 18+ стикеры, каналы и они мне не доступны. Но моим друзьям, у которых я тестил акки, им все было доступно.
Я пробовал когда-то с помощью SSLH, но тогда сайты видели все коннекты клиентов как от 127.0.0.1.
Если пока отказаться от этого FakeTLS, то средствами nginx можно проверять версию TLS (например) и неизвестные версии отправлять на МТ-прокси. В этом случае снаружи будет виден порт 443, на него можно будет соединиться стандартным клиентом и увидеть веб-сайт, но соединения от телеграм-клиентов туда же будут видны как неведомая хрень. В теории это не должно быть основанием для блока, так как такой подход используется для OpenVPN и других задач, на практике же непонятно.
Вероятно, nginx собран без модуля ngx_stream_ssl_preread_module?
В пакетах по-умолчанию его почему-то нет, надо самому собирать.
nginx version: nginx/1.16.0Может что-то не так делаю…
built by gcc 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
built with OpenSSL 1.1.0j 20 Nov 2018 (running with OpenSSL 1.1.1c 28 May 2019)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.16.0/debian/debuild-base/nginx-1.16.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
У меня работает примерно так:
map $ssl_preread_alpn_protocols $upstream {
default ssh;
~\bhttp/0.9\b web;
~\bhttp/1.0\b web;
~\bhttp/1.1\b web;
...
Но там у меня по alpn и несколько другие задачи. На web висит веб-сервер с сайтами, на ssh всякая байдистика и мтпрото там тоже есть — полёт нормальный :)
Схема примерно такая:
stream {
upstream ssh {
server localhost:550;
}
upstream web {
server localhost:410;
}
map $ssl_preread_alpn_protocols $upstream {
default ssh;
~\bhttp/0.9\b web;
~\bhttp/1.0\b web;
~\bhttp/1.1\b web;
}
server {
listen 443;
proxy_pass $upstream;
ssl_preread on;
}
}
Соответственно, ниже в конфиге веб-сервер слушает порт 410, а 550 — там уже висит прокси и ещё кое-что.
Можно попробовать намудрить примерно то же самое, но с проверкой по версии TLS или ещё чему-нибудь.
В хендшейке нет отправки сертификата сервером. И дальнейших шагов. DPI легко может блочить такую сессию как невалидную ИМХО.
Это TLSv1.3.
И если они будут мимикрировать под 1.3 то все равно сертификат нужен будет, просто он будет в том же пакете что и ServerHello.
А если сертификата нет, то для любой вменяемой DPI это знак что надо этот траффик роутить в blackhole.
Нет, телеграм маскируется под TLS 1.3
Для TLSv1.3 он в ClientHello должен посылать 0x0304 в расширении supported_versions, а сервер отвечать тем же. И Wireshark это детектит. В коде прокси я нашел только 0x0303 т.е. TLSv1.2
https://tools.ietf.org/html/rfc8446#section-4.1.2
legacy_version: In previous versions of TLS, this field was used for
version negotiation and represented the highest version number
supported by the client. Experience has shown that many servers
do not properly implement version negotiation, leading to "version
intolerance" in which the server rejects an otherwise acceptable
ClientHello with a version number higher than it supports. In
TLS 1.3, the client indicates its version preferences in the
"supported_versions" extension (Section 4.2.1) and the
legacy_version field MUST be set to 0x0303, which is the version
number for TLS 1.2. TLS 1.3 ClientHellos are identified as having
a legacy_version of 0x0303 and a supported_versions extension
present with 0x0304 as the highest version indicated therein.
(See Appendix D for details about backward compatibility.)
1) нет 0x0304 в supported_versions
2) нет сертификата
Поэтому, как мне кажется, полезность данной обфускации невелика. Вот Websockets с реальным сертификатом было бы полезнее гораздо.
Константа 0x0304 есть в коде клиента т.к. именно клиент отсылает пакет с supported_versions.
Как по мне — было бы идеально добавить способ использовать обычное TLS туннелирование (наверное с обмазкой всякими ALPN и прочим h2 чтобы выглядеть как HTTPS) и гонять MTProto уже внутри без модификаций.
Таким образом можно было бы поднять прокси на валидном TLS сертификате и полностью удовлетворять TLS-спеке если глядеть снаружи…
В клиенте есть, но прокси тоже должен ответить 0x0304 чтобы сессия выглядела валидной. Плюс, опять же, сертификат должен быть чем-то хотя-бы декодируемым в X.509.
Не знаю, запустил wireshark, дернул страничку своего сайта через TLSv1.3 + HTTP/2 — пакеты такие же, как у телеграма. Нет в ServerHello никаких 0x0304, нет X.509 сертификатов.
Наверное если активно пытаться по https подключиться, то разница будет заметна. Но в пассивном режиме не вижу разницы.
Нет в ServerHello никаких 0x0304Вот кусок ответа cloudflare.com:
нет X.509 сертификатов.Т.е. вы считаете что сертификаты не участвуют в TLS 1.3 хендшейке? :) На самом деле Wireshark, судя по всему, еще не особо умеет 1.3 разбирать. Если глянете на ServerHello там большая часть пакета вообще никак не помечена — там сертификат и едет.
Хм, да, выправы! Спасибо!
Поправил в Erlang версии: https://github.com/seriyps/mtproto_proxy/commit/5e601bce3e19cdc3d3f2b77313e3ee57b8dce482
Возможно имеет смысл реализовать что-то вроде:
1. Берем тот домен, который указан в SNI. Сейчас, как я понял, в клиенте захардкожен google.com
2. Резолвим, лезем туда по TLS на 443 порт
3. Тащим оттуда цепочку сертификатов
4. Кешируем
5. Отдаем ее всем клиентам в хендшейке
6. Повторяем пункты 1-4 в бэкграунде раз в Х минут
как я понимаю CertificateСhain едет в ApplicationData
фрейме? У меня, как и в python прокси, первый ApplicationData фрейм генерится как случайные данные случайной длины от 0 до 256:
https://github.com/seriyps/mtproto_proxy/blob/5e601bce3e19cdc3d3f2b77313e3ee57b8dce482/src/mtp_fake_tls.erl#L109
https://github.com/alexbers/mtprotoproxy/blob/e43ae9991102c8471c7f2436df63f7d64906940c/mtprotoproxy.py#L839
Возможно стоит увеличить размер?
Как я понимаю, засовывать туда реальный сертификат смысла большого нет, т.к. он зашифрован и пассивным анализом трафика его не расшифровать?
Если там нет какой-либо структуры т.е. это просто бинарный блоб который парсится только после дешифровки (а так оно скорее всего и есть, но не читал пока), то думаю достаточно генерировать побольше мусора чтобы добить размер пакета до 1.5кб и в таком случае будет неотличимо от «средней» реальной сессии с цепочкой сертификатов из 2-3 штук.
Сходу правило — «блокировать сайт, где TLS-соединения с разных клиентов дают существенно разную длину ApplicationData первого TLS-фрейма». Оно будет даже не слишком тяжёлым для DPI и не потребует активного сканирования https/tls DPI-агентом.
Следующим шагом, возможно, полезно было бы периодически дергать google.com и получать от него цепочку сертификатов — достаточно просто ее длины в зашифрованном виде. Пока в клиентах захардкожен Гугл, то можно только его юзать, а дальше по ситуации.
И отдавать клиентам не рандом в диапазоне 1..4kb а именно эту длину. Так будет еще правдоподобнее :)
Но, возможно, это уже оверкилл. Хотя реализовать не сложно.
в клиентах захардкожен Гугл
Тут одно «но»: отдать невалидному клиенту MASK_HOST:MASK_PORT с захардкоженным google.com не получится — браузер заругается, что хост, на который пришли, и домен в полученном сертификате не совпадают.
Смотря как заходить браузером. Если заходить по ip-адресу или по другому имени, то заругается, а если по правильному имени, то не заругается. Самый простой способ зайти браузером "правильно" — прописать google.com в /etc/hosts или аналогичный файл.
Аналогично ведёт себя и настоящий google.com.
Защита от каких-либо пробников, которые не зная секрета сканят адрес в поисках Telegram прокси — это ортогональная задача.
Получив первый пакет от клиента (ClientHello) мы уже понимаем знает он секрет или нет. И если он знает, то отвечаем телеграмным ServerHello с прилепленным рандомом размером с реальный Certificate Chain гугля.
А если нет, то проксируем на MASK_HOST:MASK_PORT прозрачно (это и так делается)
Единственный способ избежать этого: a) не подделывать tls_domain, а иметь настоящий, правильно ресолвящийся в ip нашего хоста; б) проксировать сайт, отдающий либо правильный сертификат с правильным хостнеймом, либо самогенерированный, но всё равно с правильным хостнеймом.
б) DPI не стучится никуда, он зеркало траффика анализирует :) Но суть понятна, стучится некая проба.
Так вот, вы сертификат который google.com отдает видели? Там в subjectAltName наверное сотня вайлдкардов вида *.google.com, *.google.co.uk и так далее. Как проба их резолвить будет? :)
Ну даже если бы это было возможно — Гугл работает через anycast и прочий GeoDNS и в зависимости откуда отправлен запрос — IP будут совсем разные. Причем они еще могут ротироваться из сотни вариантов отдавая в DNS случайные N штук.
Но суть понятна, стучится некая проба
Да. И они уже давно работают. Отложенное сканирование целевых хостов по логам подозрительной активности делается.
сотня вайлдкардов
Я понял суть вашего посыла. :) Но редиректить на гугл — это всё равно как-то не по фэн-шую. Хотя, может, я и слишком заморачиваюсь.
он зеркало траффика анализирует
Как я уже писал, достаточно проверить, что хост отвечает при установлении TLS1.3-соединения сильно рандомными по длине ApplicationData (хранящим CertChain).
б) проксировать сайт, отдающий либо правильный сертификат с правильным хостнеймом, либо самогенерированный, но всё равно с правильным хостнеймом.Проблема в том что в данный момент телеграм шлет google.com. Если они это изменят и будут в SNI отправлять hostname прокси — тогда да.
https://t.me/proxy?server=ip&port=443&secret=eesecret[hex:hostname]
, где к секрету дописано ещё и имя хоста (TLS_DOMAIN в терминах автора прокси) и запомнив её, телега отправляет в запросе совершенно нормальный SNI с именем хоста из ссылки.Я только что проверил это в wireshark.
А так, конечно, хорошо — осталось проверять размер certchain у хоста в MASK_HOST и отдавать такую же длину.
Думаю, стоит периодически опрашивать https-сервер за ним и сохранять ответы на handshake (extensions и сертификат). Причём делать несколько запросов, чтобы понять какие части extensions случайные, а какие — нет. Возможно добавлю и это тоже
PS: ssl handshake к проксе и к реальному сайту очень сильно различаются. Например, секций application data у апача две, а у телеги — одна. Так что её все равно определят и забанят, если захотят. Хотя это будет накладно, поскольку придётся парсить tls.
Вместо PyCrypto лучше использовать пакет cryptography. PyCrypto заброшен и много лет не поддерживается.
Хорошо было бы сделать нормальный python-пакет, добавить setup.py
файл и указать зависимости, для возможности установки вашего пакета стандартными средствами, например, в виртуальное окружение.
Прокси поддерживает сразу несколько библиотек:
- Cryptography
- Если Cryptography не найден, то PyCryptodome или PyCrypto
- Если ничего не найдено, то испольуется медленная реализация криптографии на Python
Python-пакет есть: https://pypi.org/project/mtprotoproxy/, правда там стабильная версия, в которой ещё нет экспериментальной поддержки TLS.
Ещё есть образ на докерхабе: https://hub.docker.com/r/alexbers/mtprotoproxy
А как вы сделали пакет на pypi? В репозитории не вижу ничего для packaging (setup.py, pyproject.toml, etc).
Я пока просто взял последнюю версию из исходников и запускаю через сервис systemd. Не люблю я докеры-шмокеры для таких простых вещей. :)
Он в параллельной ветке: https://github.com/alexbers/mtprotoproxy/tree/pypi.
С докером хорошо в том плане, что можно зафиксировать environment: версию Python и библиотек. Другие способы хороши, но поддерживать пользователей чуть сложнее, приходится спрашивать какая у них ОС, как они запускают и т.д. Это позволяет поддерживать пользователей бесплатно, не тратя на это много свободного времени.
С PyCrypto, кажется, не работает нововведение с TLS. Сервер валится если использовать expiremental-ключ:
...
mtprotoproxy/mtprotoproxy.py", line 430, in read
return self.decryptor.decrypt(data)
/lib/python3.5/site-packages/Crypto
return self._cipher.decrypt(ciphertext)
TypeError: argument must be read-only bytes-like object, not bytearray
С cryptography получилось подключиться с Android-клиента.
Зачем вообще тянуть поддержку чего-либо кроме cryptography? PyCrypto заброшен, ваша реализация медленная. Зачем это нужно, если есть нормальная библиотека, которая активно поддерживается?
Официальная последняя версия v5.10.0 (1684).
Посмотрите в логи, возможно, у вас на сервере тоже exception происходит.
Да, ключ experimental, в конфиге TLS_ONLY = False
. На двух андроид-устройствах попробовал, подключается и работает.
PORT = 1443
USERS = {
"tg": "xxx",
}
SECURE_ONLY = True
Пробовал и без SECURE_ONLY, ничего не меняется. Проксю последнюю из GIT вытянул.
Не пользуюсь вообще пакетами из репы дистра. Всегда venv и те версии пакетов, какие нужны, либо самые последние. Так всегда надёжнее, удобнее и проще.
Советую использовать PyCryptodome или cryptography,
PyCrypto заброшен, как вы верно сказали. Думаю дропнуть его поддержку.
Устранил вероятную причину такого поведения. Проверьте, пожалуйста, что стало лучше.
России пока не научились, но закон уже приняли.
Вообще нет, на yota невозможно пользоваться mtproto-проксями как раз из-за этого.
Да, вы правы, отдельные провайдеры экспериментируют с этим, но массово, как в Иране или Китае пока не блокируют по протоколу.
на yota невозможно пользоваться mtproto-проксями
не испытывал затруднений на Yota с MTProxy в dd-режиме. Хотя шейпить и детектить трафик они пытаются, да
The default secret 0123456789abcdef0123456789abcdef is used, this is not recommended
На это обращать внимание?
Конечно, поменяйте секрет на свой, сейчас там 1234...
Сгенерируйте свой собственный секрет и измените в конфиге. Генерировать так, например:
openssl rand -hex 16
Это значит, что обнаружить прокси автоматическим сканированием с перебором секретов будет легче. Лучше использовать уникальный секрет.
Пока не придумал хорошего решения для этого. С одной стороны хочется чтобы прокси как можно проще поднимался, с другой, чтобы форсились рекомендованные настройки.
Добавил более заметные сообщения о дефолтных настройках. В сообщении про секрет теперь предлагается рандомный секрет, оказалось что, многие люди не меняли секрет, из-за того, что не знали как его сгенерировать. Надеюсь, меньше людей будут игнорировать смену секрета.
Боюсь обещать, зависит от нескольких непредсказуемых факторов.
Кстати, сегодня, после двух недель тестирования и ~50 коммитов, вышел стабильный релиз прокси-сервера. Хотел бы поблагодарить людей, которые писали отличные идеи в комментарии, в личку, слали pull request'ы, рассказывали о своём опыте работы и багах с которыми они встречались.
С багами отдельная история. Так, например, один баг оказался в реализации TCP в ядре Linux. Другой — в реализации PyPy. Третий — в реализации некоторых клиентов Telegram. В предыдущих версиях баги находились в реализации asyncio и в модуле криптографии. Осталось ещё в сервере Telegram найти багу и получится полный комплект :)
Сервер расположен на AWS. Прокси работает идеально, пока в терминале так:
ubuntu@ip-136-32-17-212:~$ cd mtprotoproxy
ubuntu@ip-136-32-17-212:~/mtprotoproxy$ python3 mtprotoproxy.py
tg: tg://proxy?server=17.221.145.24&port=4433&secret=ee20200004000700004000503450600001676f6f676c6rtyu36fsd (new)
То есть я зашёл по ssh, запустил прокси от пользователя ubuntu, и он от него работает. Но стоит мне закрыть терминал, как соединение с прокси в клиенте обрывается. Насколько я понимаю, «python3 mtprotoproxy.py» перестаёт выполняться. Как оставить его работать?
Самый быстрый способ — использовать утилиту screen. Тогда будет работать до следующей перезагрузки. Как сделать чтобы работало и после перезагрузки зависит от ОС. Обычно это написание специального unit-файла для systemd. Планирую описать это подробнее в гитхабовской wiki.
Если запускать рекомендуемым способом, через docker-compose, то запуск после перезагрузки происходит автоматически.
Telegram научился маскироваться под HTTPS