Новый DPI в Перми для блокировки Telegram

Везде пишут про новый DPI который тестируют в Перми.
Якобы он успешно блокирует Telegram и mtrpoxy трафик.

Сейчас в качестве решения предлагают fake tls прокси. Официальная реализация прокси уже поддерживает TLS https://github.com/TelegramMessenger/MTProxy

Интересно можно ли положить этот прокси за обычным веб-сервером?

Немного потестировал Fake TLS на трех прокси.

  • В ClientHello всегда используется SNI google.com.
  • Сервер предоставляет настоящий, действующий сертификат для google.com.
  • Один из серверов корректно отвечает на HTTPS, т.е. проксирует запросы к настоящему google.com. Другой — сбрасывает соединение.
  • Набор ciphersuites в ClientHello мимикрирует под Chrome, похоже.
  • Клиент и сервер генерируют эфемерные (временные) ключи и передают их в Key Share extension.
  • Сервер сохраняет Session ID и блокирует повторные подключения с этим же ID, для исключения атаки на повторную отправку данных.

Бегло посмотрел код сервера alexbers/mtprotoproxy, в нём есть такая возможность, причем он даже поддерживает протокол PROXY (который из haproxy).

Но, насколько понимаю, клиент не даёт возможности указать SNI, и используется только google.com, поэтому запуск своего сайта, к которому также обращаются как к google.com, создает возможность для фингерпринтинга (хотя, наверное, и так ясно, что обращение к IP-адресу, не принадлежащему к Google, со SNI google.com — это что-то необычное).

Нет, передаётся google.com клиентом в SNI не всегда. Хостер fake tls прокси может выбрать любой удобный домен, например, какой-нибудь amazonaws.com. Особенно красиво будет, если захостить прокси на Amazon :slight_smile:
Клиент легко понимает, какой использовать домен, потому что строка secret для подключения состоит из: ee + 16-byte secret (hex) + SNI domain (hex)

Где можно почитать подробней, есть ли техническое описание реализации Fake TLS в Telegram?
Нашел: https://habr.com/ru/post/461171/

Не видел особо точных технических описаний, могу попытаться объяснить:
rfc tls1.3 https://tools.ietf.org/html/rfc8446

  1. Telegram клиент отправляет технически валидный TLS1.3 ClientHello. Все поля (кроме random) в нём не имеют смысла и в протоколе mtproto proxy ни на что не влияют. просто выглядят как валидный TLS. В поле random записан специальный хеш от ClientHello + proxy secret. В расширение sni кладётся domain который закодирован в секрете (как @koteeq заметил). Т.е. клиент решает что положить в SNI.
  2. Прокси получает этот client hello, считает хеш от него и секрета на своей стороне и сверяет с тем что пришло. Не совпало - закрываем или пробрасываем на хост из SNI. Совпало - генерируем ServerHello (тоже все поля фейковые кроме random в котором так же хеш от ClientHello + ServerHello). Так же отправляет фейковые ChangeCipherSuite и фейковый зашифрованный (tls1.3) сертификат сервера (просто рандомные данные, официальный и python прокси подбирают размер фейкового сертификата обращаясь к домену из SNI; erlang прокси просто использует рандомный размер).
  3. Клиент сверяет хеши из ServerHello и если всё ок, то отправляет TLS Frame пакет с теми самыми 64 байтами из которых вычисляются ключи шифрования и первым ашифрованным mtproto data пакетом.
  4. После этого обмен данными идёт по тому же рандомизированному dd протоколу, но к пакетам добавляется TLS Frame заголовок

Тут вот ещё можно генерировать ссылки и секреты для различных версий протокола:
http://seriyps.ru/mtpgen.html
Можно в код страницы заглянуть чтоб понять как секреты формируются

обращение к IP-адресу, не принадлежащему к Google, со SNI google.com — это что-то необычное

Не всегда. Есть GGC, например. Иногда www.google.tld терминировался и на него.

В статье написано:

Почти все поля не имеют для клиентов Telegram смысла и нужны лишь для того чтобы прикидываться TLS. Самая важную функцию несёт поле Random , куда помещается результат HMAC от общего секрета и данных в пакете, что позволяет доказать клиенту что он знает секрет. Также, клиент ксорит последние 4 байта поля Random со своим временем в формате unixtime, что позволяет прокси-серверу определять когда был сгенерирован пакет. Это полезно для защиты от replay-атак. Если пакет сгенерирован давно или в будущем, то прокси-сервер может его сразу отбросить.

Не совсем понятно про время. Время XOR’ится с последними байтами Random после HMAC, но как тогда сервер получает корректный HMAC? Там секундная точность?

Там секундная точность?

Нет. Просто то, с чем XOR-ится timestamp может быть вычеслено как на клиенте, так и на сервере (если оба знают секрет). Так что просто делается обратный XOR.
Если не лень, можно тут посмотреть. Есть реализация как сервера:

Так и клиента (клиента делал для тестов):

Первые последствия: ⚡ Автономный способ обхода DPI и эффективный способ обхода блокировок сайтов по IP-адресу. GoodbyeDPI и ReQrypt + Blockcheck (ОБНОВЛЕНО 26 Декабря 2021) стр.61 :: NNM-Club

GoodByeDPI работал. теперь перестал. ростелеком
Откуда: ХМАО

Заметка для себя: так выглядит EcoDPI от rdp.ru

BlockCheck v0.0.9.8
Для получения корректных результатов используйте DNS-сервер провайдера и отключите средства обхода блокировок.

Проверка работоспособности IPv6: IPv6 недоступен.
IP: 37.79.89.xxx, провайдер: OJSC Uralsvyazinform/ Ростелеком МРФ "Урал"

[O] Тестируем IPv4 DNS
	Через системный DNS:	 ['104.18.182.1', '104.18.183.1', '104.20.134.45', '104.20.135.45', '104.24.10.70', '104.24.11.70', '195.8.215.136', '195.82.146.214', '208.100.28.56', '67.202.114.141']
	Через Google DNS:	 ['104.18.182.1', '104.18.183.1', '104.20.134.45', '104.20.135.45', '104.24.10.70', '104.24.11.70', '195.8.215.136', '195.82.146.214', '208.100.28.56', '67.202.114.141']
	Через Google API:	 ['104.18.182.1', '104.18.183.1', '104.20.134.45', '104.20.135.45', '104.24.10.70', '104.24.11.70', '195.8.215.136', '195.82.146.214', '208.100.28.56', '67.202.114.141']
	Несуществующий DNS не вернул адресов (это не ошибка)
[✓] DNS-записи не подменяются
[✓] DNS не перенаправляется

[O] Тестируем HTTP
	Открываем  http://a.putinhuylo.com/
[✓] Сайт открывается
	Открываем  http://furry.booru.org/
[✓] Сайт открывается
	Открываем  http://furry.booru.org/index.php?page=post&s=view&id=111173
[☠] Получен неожиданный ответ, скорее всего, страница-заглушка провайдера. Пробуем через прокси.
[✓] Сайт открывается через прокси
	Открываем  http://pbooru.com/
[✓] Сайт открывается
	Открываем  http://pbooru.com/index.php?page=post&s=view&id=303026
[✓] Сайт открывается
	Открываем  http://rutracker.org/forum/index.php
[☠] Получен неожиданный ответ, скорее всего, страница-заглушка провайдера. Пробуем через прокси.
[✓] Сайт открывается через прокси

[O] Тестируем HTTPS
	Открываем  https://e621.net/
[☠] Сайт не открывается
	Открываем  https://lolibooru.moe/
[☠] Сайт не открывается
	Открываем  https://rutracker.org/forum/index.php
[☠] Сайт не открывается
	Открываем  https://www.dailymotion.com/
[☠] Сайт не открывается

[O] Тестируем обход DPI
	Пробуем способ «дополнительный пробел после GET» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «заголовок hOSt вместо Host» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «заголовок hoSt вместо Host» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «значение Host БОЛЬШИМИ БУКВАМИ» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «необычный порядок заголовков» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «отсутствие пробела между двоеточием и значением заголовка Host» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «перенос строки в заголовках в UNIX-стиле» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «перенос строки перед GET» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «табуляция в конце домена» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «точка в конце домена» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «фрагментирование заголовка» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «фрагментирование заголовка, hoSt и отсутствие пробела одновременно» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «дополнительный пробел после GET» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «заголовок hOSt вместо Host» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «заголовок hoSt вместо Host» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «значение Host БОЛЬШИМИ БУКВАМИ» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «необычный порядок заголовков» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «отсутствие пробела между двоеточием и значением заголовка Host» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «перенос строки в заголовках в UNIX-стиле» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «перенос строки перед GET» на rutracker.org
[✓] Сайт открывается
	Пробуем способ «табуляция в конце домена» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «точка в конце домена» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «фрагментирование заголовка» на rutracker.org
[☠] Сайт не открывается
	Пробуем способ «фрагментирование заголовка, hoSt и отсутствие пробела одновременно» на rutracker.org
[☠] Сайт не открывается

[!] Результат:
[⚠] Ваш провайдер полностью блокирует доступ к HTTPS-сайтам из реестра.
[⚠] У вашего провайдера "обычный" DPI. Вам поможет HTTPS/Socks прокси, VPN или Tor.

Стоит два DPI: новый in-path, и старый Ростелекомовский за ним, on-path.

Перенаправление происходит теперь на http://warning.rt.ru, без get-параметров, а раньше параметрами передавался заблокированный домен, на который пользователь попытался зайти. Часто перенаправления (для HTTP) и TCP RST (для HTTPS) присылаются с большой задержкой, видимо, искусственной: от 2 до 16 секунд. Раньше такого не было.
Это, к слову, третий DPI у Ростелекома, и все они подключены одновременно. Второй — вот такой: Интереснная особенность DPI Ростелекома

А про EcoDPI это установленный другим методом факт или всё же предположение на основании публикаций в СМИ о роли rdp.ru в процессе? Я слышал мнения, что RDP хотели подвинуть от “кормушки” и, я допускаю, что-то даже и произошло.

Это только моё предположение. Но, подозреваю, что это действительно EcoDPI.

1 Like

Результат blockcheck tls_experiment_v1

BlockCheck v0.0.9.8-tls_experiment_v1
Для получения корректных результатов используйте DNS-сервер провайдера и отключите средства обхода блокировок.

Проверка работоспособности IPv6: IPv6 недоступен.
IP: 188.17.169.xxx, провайдер: OJSC Uralsvyazinform/ Ростелеком МРФ "Урал"

[O] Тестируем IPv4 DNS
	Через системный DNS:	 ['104.18.182.1', '104.18.183.1', '104.20.134.45', '104.20.135.45', '104.24.10.70', '104.24.11.70', '195.8.215.136', '195.82.146.214', '208.100.28.56', '67.202.114.141']
	Через Google DNS:	 ['104.18.182.1', '104.18.183.1', '104.20.134.45', '104.20.135.45', '104.24.10.70', '104.24.11.70', '195.8.215.136', '195.82.146.214', '208.100.28.56', '67.202.114.141']
	Через Google API:	 ['104.18.182.1', '104.18.183.1', '104.20.134.45', '104.20.135.45', '104.24.10.70', '104.24.11.70', '195.8.215.136', '195.82.146.214', '208.100.28.56', '67.202.114.141']
	Несуществующий DNS не вернул адресов (это не ошибка)
[✓] DNS-записи не подменяются
[✓] DNS не перенаправляется

[O] Тестируем HTTP
	Открываем  http://a.putinhuylo.com/
[✓] Сайт открывается
	Открываем  http://furry.booru.org/
[✓] Сайт открывается
	Открываем  http://furry.booru.org/index.php?page=post&s=view&id=111173
[☠] Сайт не открывается, пробуем через прокси
[✓] Сайт открывается через прокси
	Открываем  http://pbooru.com/
[✓] Сайт открывается
	Открываем  http://pbooru.com/index.php?page=post&s=view&id=303026
[✓] Сайт открывается
	Открываем  http://rutracker.org/forum/index.php
[☠] Сайт не открывается, пробуем через прокси
[✓] Сайт открывается через прокси

[O] Тестируем HTTPS
	Открываем  https://e621.net/
[✓] Сайт открывается
	Открываем  https://lolibooru.moe/
[✓] Сайт открывается
	Открываем  https://rutracker.org/forum/index.php
[☠] Сайт не открывается
	Открываем  https://www.dailymotion.com/
[☠] Сайт не открывается

[O] Тестируем обход DPI
	Пробуем способ «дополнительный пробел после GET» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «заголовок hOSt вместо Host» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «заголовок hoSt вместо Host» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «значение Host БОЛЬШИМИ БУКВАМИ» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «необычный порядок заголовков» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «отсутствие пробела между двоеточием и значением заголовка Host» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «перенос строки в заголовках в UNIX-стиле» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «перенос строки перед GET» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «табуляция в конце домена» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «точка в конце домена» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «фрагментирование заголовка» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «фрагментирование заголовка, hoSt и отсутствие пробела одновременно» на pbooru.com
[☠] Сайт не открывается
	Пробуем способ «дополнительный пробел после GET» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «заголовок hOSt вместо Host» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «заголовок hoSt вместо Host» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «значение Host БОЛЬШИМИ БУКВАМИ» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «необычный порядок заголовков» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «отсутствие пробела между двоеточием и значением заголовка Host» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «перенос строки в заголовках в UNIX-стиле» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «перенос строки перед GET» на rutracker.org
[✓] Сайт открывается
	Пробуем способ «табуляция в конце домена» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «точка в конце домена» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «фрагментирование заголовка» на rutracker.org
[☠] Ошибка: timeout('timed out')
	Пробуем способ «фрагментирование заголовка, hoSt и отсутствие пробела одновременно» на rutracker.org
[☠] Ошибка: timeout('timed out')

[O] Тестируем обход DPI (HTTPS)
	 Пробуем Обычный запрос на dailymotion.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello без SNI на dailymotion.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding на dailymotion.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding и SNI только в конце padding на dailymotion.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на dailymotion.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на dailymotion.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем Обычный запрос на danbooru.donmai.us
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello без SNI на danbooru.donmai.us
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding на danbooru.donmai.us
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding и SNI только в конце padding на danbooru.donmai.us
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на danbooru.donmai.us
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на danbooru.donmai.us
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем Обычный запрос на e621.net
[✓] Сайт открывается
	 Пробуем ClientHello без SNI на e621.net
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding на e621.net
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding и SNI только в конце padding на e621.net
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на e621.net
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на e621.net
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем Обычный запрос на gelbooru.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello без SNI на gelbooru.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding на gelbooru.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding и SNI только в конце padding на gelbooru.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на gelbooru.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на gelbooru.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем Обычный запрос на rutracker.org
[☠] Ошибка (TLS): ConnectionResetError(10054, 'Удаленный хост принудительно разорвал существующее подключение', None, 10054, None)
	 Пробуем ClientHello без SNI на rutracker.org
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding на rutracker.org
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding и SNI только в конце padding на rutracker.org
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на rutracker.org
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на rutracker.org
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем Обычный запрос на zello.com
[☠] Ошибка (TLS): timeout('_ssl.c:1059: The handshake operation timed out')
	 Пробуем ClientHello без SNI на zello.com
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding на zello.com
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding и SNI только в конце padding на zello.com
[✓] Сайт открывается
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным до padding на zello.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')
	 Пробуем ClientHello с большим padding, поддельным SNI в начале и правильным после padding на zello.com
[☠] Ошибка (TLS): SSLError(1, '[SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:1076)')

[!] Результат:
[⚠] Ваш провайдер полностью блокирует доступ к HTTPS-сайтам из реестра.
[⚠] У вашего провайдера "обычный" DPI. Вам поможет HTTPS/Socks прокси, VPN или Tor.

Новый DPI установили вне Свердловской области — в Мурманской области.
https://rutracker.org/forum/viewtopic.php?p=78125766#78125766

Мурманская область, провайдер Олтелеком, Win 7x64. Goodbyedpi не помогает. Еще месяц назад сидел на Ростелекоме и все работало. :frowning: